react-mk
v2.0.0
Published
A lightweight, zero-dependency React typewriter component with realistic typing animations.
Maintainers
Readme
A lightweight, zero-dependency React typewriter component with realistic typing animations.
Features
- Zero dependencies — no CSS-in-JS library required, works right out of the box
- Modern React 19+ — built with hooks and the
react-jsxtransform useTypewriterhook — extract the core engine for fully custom UIs- Declarative actions — composable
type(),pause(),deleteAll(),deleteChars()builders sentencesprop — cycle through an array of strings with one prop- Looping — infinite or N iterations via the
loopprop - Realistic typo simulation — set
mistakeChancefor QWERTY-aware "mistake → correct" animations - Live speed changes — dynamically update
typeSpeed/deleteSpeedmid-animation - Callbacks —
onType,onDelete,onFinish,onLoop - Accessible —
aria-hiddencursor, automaticprefers-reduced-motionsupport - Tree-shakeable ESM — modern
exportsfield withsideEffects: false - Fully typed — comprehensive TypeScript definitions with JSDoc
Install
npm i react-mkQuick Start
import Typewriter, { Cursor } from 'react-mk';
function App() {
return (
<p>
<Typewriter>Hello World</Typewriter>
<Cursor />
</p>
);
}Usage
Simple Text
<Typewriter>Any string or number works here</Typewriter>Action Sequences
Use the render-prop pattern to compose typing, pausing, and deleting:
<Typewriter>
{({ type, pause, deleteAll }) => [
type('Hello World'),
pause(2000),
deleteAll(),
type('React MK v2'),
]}
</Typewriter>Sentence Cycling
The sentences prop makes it trivial to cycle through an array of strings:
<Typewriter
sentences={['First sentence', 'Second sentence', 'Third sentence']}
sentenceDelay={2000}
loop
/>useTypewriter Hook
For full control, use the hook directly:
import { useTypewriter, type, pause, deleteAll, Cursor } from 'react-mk';
function CustomTypewriter() {
const { text, phase } = useTypewriter(
[type('Hello'), pause(1000), deleteAll(), type('World')],
{ loop: true, typeSpeed: [40, 80] },
);
return (
<h1>
{text}
{phase !== 'complete' && <Cursor />}
</h1>
);
}Realistic Typos
Add mistakeChance for humanized typing that makes QWERTY-adjacent mistakes and self-corrects:
<Typewriter mistakeChance={0.06} typeSpeed={[60, 120]}>
This text will have occasional realistic typos that get corrected
</Typewriter>Custom Cursors
<Cursor /> {/* Default: blinking | */}
<Cursor blink={false}>_</Cursor> {/* Static underscore */}
<Cursor blinkSpeed={300}>█</Cursor> {/* Fast-blinking block */}API Reference
<Typewriter> Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | string \| number \| ((builders) => Action[]) | — | Content to type or render-prop returning actions |
| sentences | string[] | — | Array of sentences to cycle through (takes priority over children) |
| sentenceDelay | number | 2000 | Ms each sentence is shown before deletion |
| typeSpeed | [min, max] | [50, 90] | Delay range between keystrokes (ms) |
| deleteSpeed | [min, max] | [30, 60] | Delay range between deletions (ms) |
| loop | boolean \| number | false | true for infinite, or a number for N iterations |
| loopDelay | number | 1000 | Ms before restarting the loop |
| startDelay | number | 0 | Ms before the animation begins |
| mistakeChance | number | 0 | Probability (0–1) of a typo per character |
| onType | (char, text) => void | — | Called after each character is typed |
| onDelete | (char, text) => void | — | Called after each character is deleted |
| onFinish | () => void | — | Called when all actions complete |
| onLoop | (count) => void | — | Called when the animation loops |
useTypewriter(actions, options)
Returns { text, phase, loopCount }.
text— The currently displayed stringphase— One of'idle' | 'typing' | 'deleting' | 'pausing' | 'complete'loopCount— Current loop iteration (0-indexed)
<Cursor> Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| blink | boolean | true | Enable/disable blink animation |
| blinkSpeed | number | 530 | Blink cycle duration (ms) |
| children | ReactNode | \| | Cursor character(s) |
| ...rest | HTMLSpanElement props | — | Spread to the root <span> |
Action Builders
| Builder | Description |
|---------|-------------|
| type(text) | Type a string character by character |
| pause(ms) | Pause for a duration in milliseconds |
| deleteAll() | Delete all currently displayed text |
| deleteChars(n) | Delete n characters from the end |
Migration from v1
Keyboard→Typewriter(default export renamed)@emotion/cssremoved — Cursor now uses pure CSS, no imports neededkeyPressDelayRange→typeSpeedsentenceDelayPerCharRange→ Usesentences+sentenceDelaypropsblinkAnimationDuration→blinkSpeedtype()render-prop now returns explicit action objects instead of mixed arrays- New:
useTypewriterhook,deleteChars,loop,mistakeChance, callbacks
