A lightweight React hook for terminal-style typewriter effects with cursor animation, loop support, and full TypeScript support.
π Live Demo
See the hook in action with interactive examples showcasing different configurations.
- π― Zero dependencies - only React as peer dependency
- π TypeScript support - full type definitions included
- π Loop mode - auto delete and retype text
- β‘ Configurable speeds - separate delays for typing, deleting, and pauses
- π±οΈ Cursor control - configurable cursor blink speed
- βοΈ React 18+ compatible - works with StrictMode
- πͺΆ Lightweight - ~1KB minified
npm install react-terminal-typewriteryarn add react-terminal-typewriterpnpm add react-terminal-typewriterimport { useTypewriter } from 'react-terminal-typewriter'
function App() {
const { displayText, cursorBlinkSpeed } = useTypewriter({
text: 'Hello, World!',
delay: 100,
loop: true
})
return (
<h1>
{displayText}
<span
className="cursor"
style={{
'--cursor-blink-speed': `${cursorBlinkSpeed}ms`
} as React.CSSProperties}
/>
</h1>
)
}| Option | Type | Default | Description |
|---|---|---|---|
text |
string |
required | Text to type |
delay |
number |
100 |
Delay between typing each character (ms) |
startDelay |
number |
500 |
Delay before starting to type (ms) |
loop |
boolean |
false |
Enable loop mode - text will be deleted and retyped |
loopDelay |
number |
2000 |
Delay before starting to delete (ms) |
deleteDelay |
number |
50 |
Delay between deleting each character (ms) |
cursorBlinkSpeed |
number |
800 |
Cursor blink animation speed (ms) |
| Value | Type | Description |
|---|---|---|
displayText |
string |
Current displayed text |
isTyping |
boolean |
Whether currently typing |
isDeleting |
boolean |
Whether currently deleting |
isComplete |
boolean |
Whether typing is complete (only when loop is false) |
cursorBlinkSpeed |
number |
Cursor blink speed for CSS variable |
const { displayText } = useTypewriter({
text: 'Hello, World!'
})
return <p>{displayText}</p>const { displayText, isDeleting } = useTypewriter({
text: 'React Terminal Typewriter',
loop: true,
loopDelay: 3000, // Wait 3s before deleting
deleteDelay: 30 // Delete faster than typing
})
return (
<h1>
{displayText}
<span className={`cursor ${isDeleting ? 'deleting' : ''}`} />
</h1>
)const { displayText, cursorBlinkSpeed } = useTypewriter({
text: 'Custom cursor style',
cursorBlinkSpeed: 500 // Faster blink
})
return (
<div>
{displayText}
<span
className="cursor"
style={{
'--cursor-blink-speed': `${cursorBlinkSpeed}ms`
} as React.CSSProperties}
/>
</div>
)Add this CSS for the blinking cursor effect:
.cursor {
display: inline-block;
width: 3px;
height: 1em;
background-color: currentColor;
margin-left: 2px;
vertical-align: text-bottom;
animation: cursor-blink var(--cursor-blink-speed, 800ms) step-end infinite;
}
@keyframes cursor-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}import { useTypewriter } from 'react-terminal-typewriter'
function Terminal() {
const { displayText, cursorBlinkSpeed } = useTypewriter({
text: 'npm install react-terminal-typewriter',
delay: 50,
startDelay: 1000
})
return (
<div className="terminal">
<span className="prompt">$ </span>
<span className="command">{displayText}</span>
<span
className="cursor"
style={{ '--cursor-blink-speed': `${cursorBlinkSpeed}ms` } as React.CSSProperties}
/>
</div>
)
}Works in all modern browsers that support ES2020:
- Chrome 80+
- Firefox 74+
- Safari 14+
- Edge 80+
Contributions are welcome! Please read the contributing guidelines first.
Vitalii Petrenko
- Website: vitalii4reva.com
- GitHub: @vitalii4reva
- npm: vitalii4reva
MIT Β© Vitalii Petrenko