Skip to main content

useTypewriter Hook

The core hook that provides typewriter animation functionality with full TypeScript support and accessibility features.

Basic Usage

import { useTypewriter } from 'use-typewriter-animation';

function MyComponent() {
const { typewriter, elements, cursor, keyframes } = useTypewriter({
typeSpeed: 50,
cursorStyle: 'bar',
});

useEffect(() => {
typewriter.type('Hello, World!').pauseFor(1000).deleteLetters(9).type('React!').start();
}, []);

return (
<>
<style>{keyframes}</style>
<div>
{elements}
{cursor}
</div>
</>
);
}

Hook Signature

function useTypewriter(options?: UseTypewriterOptions): UseTypewriterReturn;

Options (UseTypewriterOptions)

Visual Settings

OptionTypeDefaultDescription
typeSpeednumber30Typing speed in milliseconds per character
deleteSpeednumber30Deleting speed in milliseconds per character
loopbooleanfalseWhether animation should loop continuously
cursorStyle'bar' | 'block' | 'underline''bar'Visual style of the cursor
cursorColorstring'black'CSS color value for the cursor
cursorBlinkSpeednumber500Cursor blink speed in milliseconds
enableCursorbooleantrueWhether to show the cursor

Accessibility Settings

OptionTypeDefaultDescription
ariaLive'polite' | 'assertive' | 'off''polite'ARIA live region type
ariaLabelstringundefinedARIA label for the typewriter
role'status' | 'log' | 'alert''status'ARIA role for the container
respectReducedMotionbooleantrueHonor prefers-reduced-motion setting
reducedMotionFallback'instant' | 'slow''instant'Behavior when reduced motion is preferred
enableKeyboardControlsbooleanfalseEnable keyboard shortcuts
autoKeyboardHandlingbooleanfalseAutomatically handle keyboard events
announceCompletionbooleanfalseAnnounce when typing completes
screenReaderTextstringundefinedAlternative text for screen readers

Performance Settings

OptionTypeDefaultDescription
enableVirtualizationbooleanfalseEnable virtualization for long text
maxVisibleSegmentsnumber100Maximum visible segments when virtualized

Keyboard Controls

OptionTypeDefaultDescription
keyboardShortcutsKeyboardShortcutsSee belowCustom keyboard shortcuts

Default Keyboard Shortcuts

{
pause: ['Space', ' '],
resume: ['Space', ' '],
skip: ['Escape', 'Enter'],
reset: ['KeyR']
}

Return Value (UseTypewriterReturn)

PropertyTypeDescription
typewriterTypewriterBaseTypeControl methods for the typewriter
stateTypewriterStateCurrent state of the typewriter
elementsJSX.Element[]Rendered text segments
cursorJSX.Element | nullCursor element
stylestypeof typewriterStylesCSS-in-JS styles
keyframesstringCSS keyframes for animations
metricsPerformanceMetricsPerformance metrics
accessibilityPropsAriaAttributesARIA attributes for container
screenReaderAnnouncementJSX.ElementScreen reader content

Typewriter Control Methods

Text Operations

type(text: string, options?: TypeOptions)

Types the specified text with optional configuration.

typewriter.type('Hello, World!', {
speed: 80,
screenReaderText: 'Hello, World!',
announceCompletion: true,
});

TypeOptions:

  • speed?: number - Override default typing speed
  • screenReaderText?: string - Alternative text for screen readers
  • announceCompletion?: boolean - Whether to announce completion

deleteLetters(count: number)

Deletes the specified number of characters from the end.

typewriter.deleteLetters(5); // Delete last 5 characters

deleteWords(count: number)

Deletes the specified number of words from the end.

typewriter.deleteWords(2); // Delete last 2 words

deleteAll()

Deletes all text.

typewriter.deleteAll();

Styling Operations

colorize(color: string)

Changes the color for subsequent text.

typewriter
.type('This is ')
.colorize('red')
.type('red text')
.colorize('') // Reset to default
.type(' and this is normal');

highlight(start: number, length: number, style: HighlightStyle)

Highlights a portion of existing text.

typewriter.type('Hello World').highlight(0, 5, {
color: 'white',
background: 'blue',
});

HighlightStyle:

interface HighlightStyle {
color?: string;
background?: string;
fontWeight?: string;
textDecoration?: string;
}

Flow Control

pauseFor(duration: number)

Pauses the animation for the specified duration in milliseconds.

typewriter
.type('Hello')
.pauseFor(1000) // Wait 1 second
.type(' World!');

newLine()

Inserts a line break.

typewriter.type('First line').newLine().type('Second line');

Animation Control

start()

Starts the typewriter animation.

typewriter.type('Hello, World!').start();

stop()

Stops the animation and cleans up resources.

typewriter.stop();

pause()

Pauses the current animation (keyboard control).

typewriter.pause();

resume()

Resumes a paused animation (keyboard control).

typewriter.resume();

skip()

Skips to the end of the current animation (keyboard control).

typewriter.skip();

reset()

Resets the typewriter to its initial state (keyboard control).

typewriter.reset();

isPaused(): boolean

Returns whether the animation is currently paused.

const paused = typewriter.isPaused();

Event Handling

on(event: string, callback: Function)

Registers an event listener.

typewriter
.on('start', () => console.log('Animation started'))
.on('end', () => console.log('Animation completed'))
.on('loop', () => console.log('Loop iteration'))
.on('pause', () => console.log('Animation paused'))
.on('resume', () => console.log('Animation resumed'));

Available Events:

  • start - Animation begins
  • end - Animation completes
  • loop - Loop iteration starts
  • pause - Animation is paused
  • resume - Animation is resumed
  • type - Character is typed
  • delete - Character is deleted

State Management

TypewriterState

interface TypewriterState {
isRunning: boolean;
isPaused: boolean;
currentText: string;
segments: TextSegment[];
currentSegmentIndex: number;
reducedMotion: boolean;
}

Performance Metrics

interface PerformanceMetrics {
totalSegments: number;
visibleSegments: number;
isVirtualized: boolean;
renderTime: number;
memoryUsage: number;
}

Advanced Usage

Chaining Operations

useEffect(() => {
typewriter
.type('Welcome to ')
.colorize('#3b82f6')
.type('React')
.colorize('')
.type('!')
.pauseFor(1000)
.deleteLetters(1)
.type(' with TypeScript!')
.start();
}, []);

Conditional Logic

useEffect(() => {
const greeting = new Date().getHours() < 12 ? 'Good morning' : 'Good evening';

typewriter.type(greeting).pauseFor(500).type(', welcome to our app!').start();
}, []);

Loop with Variations

const messages = ['Hello!', 'Bonjour!', 'Hola!', 'こんにちは!'];

useEffect(() => {
let index = 0;

const typeMessage = () => {
typewriter
.deleteAll()
.type(messages[index])
.pauseFor(2000)
.on('end', () => {
index = (index + 1) % messages.length;
setTimeout(typeMessage, 500);
})
.start();
};

typeMessage();
}, []);

TypeScript Support

The hook is fully typed with comprehensive TypeScript definitions:

import type {
UseTypewriterOptions,
UseTypewriterReturn,
TypewriterState,
PerformanceMetrics,
} from 'use-typewriter-animation';

const options: UseTypewriterOptions = {
typeSpeed: 50,
cursorStyle: 'bar',
respectReducedMotion: true,
};

const { typewriter, elements, cursor, state, metrics }: UseTypewriterReturn =
useTypewriter(options);

Best Practices

1. Always Include Keyframes

return (
<>
<style>{keyframes}</style> {/* Required for animations */}
<div>
{elements}
{cursor}
</div>
</>
);

2. Use Accessibility Props

<div
{...accessibilityProps}
tabIndex={0} // For keyboard controls
>
{elements}
{cursor}
{screenReaderAnnouncement}
</div>

3. Handle Cleanup

useEffect(() => {
typewriter.type('Hello').start();

return () => {
typewriter.stop(); // Cleanup on unmount
};
}, []);

4. Optimize for Performance

const { typewriter } = useTypewriter({
enableVirtualization: true, // For long text
maxVisibleSegments: 50,
respectReducedMotion: true,
});

See Also