🚀 React Markdown Typing Animation Component
If you need styling, support for math formulas, and mermaid chart rendering, we recommend ds-markdown
🇨🇳 中文 | 🇺🇸 English
A React component designed for modern AI applications, providing smooth real-time typing animations and full Markdown rendering capabilities.
Do regular typewriters stutter with AI streaming data? We don't. Automatically splits each chunk into characters, ensuring smooth character-by-character rendering no matter how much the backend pushes at once.
- Built on industry-standard react-markdown
- Zero additional dependencies, works out of the box
Not just playing animations, but also pause, resume, restart, and clear. Full imperative API gives you complete control.
Compatible with the entire remark/rehype plugin ecosystem, easily extend functionality. Supports code highlighting, math formulas, tables, custom cursors, and more.
- Native TypeScript support
- Complete type definitions
Use Cases
AI Chat Assistants · Real-time Q&A Systems · Online Education Platforms · Product Demos · Interactive Documentation · Knowledge Base Display
npm install react-markdown-typerimport MarkdownTyper from 'react-markdown-typer';
function App() {
return (
<MarkdownTyper interval={20}>
# Hello World
This is a **high-performance** typing animation component!
- ⚡ Smooth rendering
- 🎯 Perfect syntax support
</MarkdownTyper>
);
}import { useRef, useEffect } from 'react';
import { MarkdownTyperCMD, MarkdownTyperCMDRef } from 'react-markdown-typer';
function ChatDemo() {
const cmdRef = useRef<MarkdownTyperCMDRef>(null);
useEffect(() => {
// Simulate streaming data
async function simulateStreaming() {
const chunks = ['# AI Response\n\n', 'This', 'is', 'a', 'streaming', 'response'];
for (const chunk of chunks) {
await new Promise(resolve => setTimeout(resolve, 100));
cmdRef.current?.push(chunk);
}
}
simulateStreaming();
}, []);
return (
<MarkdownTyperCMD
ref={cmdRef}
interval={30}
/>
);
}// String cursor
<MarkdownTyperCMD
ref={cmdRef}
showCursor={true}
cursor="|"
interval={50}
/>
// Custom ReactNode cursor
<MarkdownTyperCMD
ref={cmdRef}
showCursor={true}
cursor={
<span style={{
color: '#007acc',
animation: 'blink 1s infinite'
}}>|</span>
}
interval={50}
/>const cmdRef = useRef<MarkdownTyperCMDRef>(null);
// Control methods
cmdRef.current?.stop(); // Pause
cmdRef.current?.resume(); // Resume
cmdRef.current?.restart(); // Restart
cmdRef.current?.clear(); // Clear| Property | Type | Default | Description |
|---|---|---|---|
children |
string |
- | Markdown content (required) |
interval |
number | IntervalType |
30 |
Typing interval (milliseconds) |
timerType |
'setTimeout' | 'requestAnimationFrame' |
'setTimeout' |
Timer type |
showCursor |
boolean |
false |
Whether to show cursor |
cursor |
React.ReactNode |
"|" |
Cursor content |
disableTyping |
boolean |
false |
Disable typing animation |
autoStartTyping |
boolean |
true |
Auto start typing |
onStart |
(data) => void |
- | Typing start callback |
onEnd |
(data) => void |
- | Typing end callback |
onTypedChar |
(data) => void |
- | Callback after each character |
reactMarkdownProps |
Options |
- | react-markdown configuration |
Same as MarkdownTyper, but without children.
| Method | Description |
|---|---|
start() |
Start typing animation |
stop() |
Pause typing animation |
resume() |
Resume typing animation |
restart() |
Restart animation |
| Method | Parameters | Description |
|---|---|---|
push(content) |
string |
Add content and start typing |
clear() |
- | Clear all content and state |
start() |
- | Start typing animation |
stop() |
- | Pause typing animation |
resume() |
- | Resume typing animation |
restart() |
- | Restart animation |
Supports dynamic typing speed:
type IntervalType = number | {
max: number; // Maximum interval
min: number; // Minimum interval
curve?: 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
curveFn?: (x: number) => number; // Custom curve function
}Example:
<MarkdownTyper
interval={{
min: 10,
max: 100,
curve: 'ease-out' // Fast start, slow end
}}
>
Content...
</MarkdownTyper>Install KaTeX plugins:
npm install remark-math rehype-katex katexUsage:
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import 'katex/dist/katex.min.css';
<MarkdownTyper
interval={20}
reactMarkdownProps={{
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex]
}}
>
Inline formula: $E = mc^2$
Block formula:
$$
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
$$
</MarkdownTyper>Fully compatible with react-markdown plugin ecosystem:
import rehypeHighlight from 'rehype-highlight';
import remarkGfm from 'remark-gfm';
import 'highlight.js/styles/github.css';
<MarkdownTyper
reactMarkdownProps={{
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight]
}}
>
```javascript
console.log('Syntax highlighting');- Time-driven, batch character processing
- Synchronized with browser 60fps refresh rate
- Suitable for high-frequency typing (interval < 16ms)
- Single character processing, fixed interval
- Precise time control
- Suitable for low-frequency typing or scenarios requiring precise rhythm
// High frequency: recommend requestAnimationFrame
<MarkdownTyper interval={5} timerType="requestAnimationFrame">
Fast typing
</MarkdownTyper>
// Low frequency: recommend setTimeout
<MarkdownTyper interval={100} timerType="setTimeout">
Slow typing
</MarkdownTyper><MarkdownTyper
customConvertMarkdownString={(str) => {
// Custom processing logic
return str.replace(/\[([^\]]+)\]\(([^)]+)\)/g,
'<a href="$2" target="_blank">$1</a>');
}}
>
[Link](https://example.com)
</MarkdownTyper><MarkdownTyper
onStart={(data) => console.log('Typing started', data)}
onEnd={(data) => console.log('Typing ended', data)}
onTypedChar={(data) => {
console.log('Progress:', data.percent + '%');
}}
>
Content...
</MarkdownTyper>const [disable, setDisable] = useState(false);
<MarkdownTyper disableTyping={disable}>
Content displays immediately, no animation
</MarkdownTyper>Clone the repository to view complete examples:
git clone https://github.com/onshinpei/react-markdown-typer.git
cd react-markdown-typer
npm install
npm run devExample locations:
example/basic/- Basic usageexample/cmd/- Imperative APIexample/cursor/- Cursor effectsexample/katex/- Math formulas
Issues and Pull Requests are welcome!
MIT © onshinpei
- react-markdown - Markdown rendering core
- ds-markdown - Enhanced version with styling (supports mermaid charts)