Typewriter
Typewriter
is a 1.3kb React component for creating realistic typewriter animations. It emulates natural human typing behaviour, handles dynamic content (with intelligent backspacing), and provides full playback control for scroll-triggered effects. All while ensuring screen reader accessibility.
<Typewriter>Hello world!</Typewriter>
Typewriter
is exclusive to Motion+ members. Motion+ is a one-time payment, lifetime membership that unlocks exclusive components, premium examples and access to a private Discord community.
Features
Natural animation: Typing speeds and variance emulate real-world behaviour.
Playback control: Easily play and pause animations, perfect for scroll-triggered animations.
Accessible: Correct ARIA labels for screen reader compatibility.
Reactive: Will animate with backspace and typing to the latest provided value.
Customisable: Control everything from typing speed and variance to cursor style and blink speed.
Install
First, add the Motion+ library to your project using your private token. You need to be a Motion+ member to generate a private token.
npm install https://api.motion.dev/registry\?package\=motion-plus\&version\=1.5.4\&token
Once installed, Typewriter
can be imported via motion-plus/react
:
import { Typewriter } from "motion-plus/react"
Usage
By passing a string as the Typewriter
child, it will animate that text in character by character.
<Typewriter>Hello world!</Typewriter>
Dynamic content
When the children
prop changes, Typewriter
will intelligently animate from the old text to the new text. By default, it backspaces character by character to the point of difference and then types out the new content.
By default, each character will be backspaced individually. Using the backspace
prop we can also backspace each word/special character:
<Typewriter backspace="word">{text}</Typewriter>
Or remove all the mismatching content immediately:
<Typewriter backspace="all">{text}</Typewriter>
Adjust speed
The animation will emulate "normal" real-world typing speeds, based on real research. It's also possible to set speed as "fast"
, "slow"
, or a custom interval (in milliseconds).
<Typewriter speed="slow">Hello world!</Typewriter>
By default, the typing speed will vary naturally per character, based on the type of content being "typed".
For example, typing will slow down while typing long words, while at the start/end of a word, when using punctuation, or when using uncommon character combinations.
This can be configured with the variance
prop. This is a 0
-1
factor applied to speed
, to create a range of speeds that we can randomly select between.
So for instance if we want no variance then we can set this to 0
.
<Typewriter variance={0}>Hello world!</Typewriter>
Or to have some variance it could be set to 0.5
:
<Typewriter variance={0.5}>Hello world!</Typewriter>
Cursor blink speed
Emulating real-world cursors, the cursor doesn't animate during an active typing animation.
Before or after typing, the cursor completes a blink cycle in 0.5
seconds. This can be adjusted using cursorBlinkDuration
:
<Typewriter cursorBlinkDuration={2}>Hello world!</Typewriter>
Playback control
Animations will play by default, but can be paused at any time by setting play={false}
.
This control makes it straightforward to, for instance, play animations only when they're within the viewport.
const ref = useRef(null) const isInView = useInView(ref) return ( <Typewriter ref={ref} play={isInView}> Hello world! </Typewriter> )
Props
as
Default: "span"
Set an element to render as.
<Typewriter as="h1">Hello world!</Typewriter>
speed
Default: "normal"
The typing speed of the animation.
Set as "slow"
, "normal"
or "fast"
to use a preset typing speed.
Or set as a duration, in milliseconds, to wait between keystrokes.
<Typewriter speed={90}>Hello world!</Typewriter>
variance
Default: "natural"
The amount of variance between the timing of each character.
By default, this is set to "natural"
. This will modify the timing between each character based on various factors:
Long words
Start/end of words
Punctuation
Uncommon character combinations
It can also be set to a factor where the speed can vary by the provided factor. For instance, setting to 0
will ensure a constant speed
:
// Constant 40ms between each character <Typewriter speed={40} variance={0}>
Whereas if we set this to 0.5
, then the speed can vary between speed
plus/minus variance x speed
:
// Between 20ms and 60ms for each character <Typewriter speed={40} variance={0.5}>
play
Default: true
Animation will pause when play
is false
. For example, this can be used to play animations only when elements appear on screen.
const ref = useRef(null) const isInView = useInView(ref) return ( <Typewriter ref={ref} play={isInView}> Hello world! </Typewriter> )
replace
Default: "type"
When the content changes, this sets the strategy for replacing the content.
"type"
: Type from the current content to the new content."all"
: Instantly delete existing content and start from scratch.
backspace
Default: "character"
When the content changes in replace: "type"
mode, Typewriter
will animate back to the closest matching value between the old and new values using emulated backspaces.
This behaviour can be configured using the backspace
prop:
"character"
: Backspace each character individually."word"
: Backspace each word (emulate option-backspace)."all"
: Delete everything instantly.
<Typewriter backspace="all"> {content} </Typewriter>
backspaceFactor
Default: 0.2
Configures the interval of each backspace with a factor that is relative to speed
. For instance, if speed
is set to 100
, then a factor of 0.1
will make each backspace 10ms.
Setting via a factor vs an absolute duration ensures you can adjust only speed
and the whole animation will scale appropriately.
cursorBlinkDuration
Default: 0.5
When the cursor is blinking, the blink animation will take this long (in seconds).
<Typewriter cursorBlinkDuration={1}>
cursorClassName
Apply this class to the cursor element for styling with CSS.
<Typewriter cursorClassName="cursor">
cursorStyle
Apply styles directly to the cursor element.
<Typewriter cursorStyle={{ backgroundColor: "red" }}>
textClassName
Apply this class to the inner text element for styling with CSS.
<Typewriter textClassName="typewriter-text">
textStyle
Apply styles directly to the cursor element.
<Typewriter textStyle={{ color: "red" }}>
onComplete
Callback to fire when the animation completes.
Typewriter
is a 1.3kb React component for creating realistic typewriter animations. It emulates natural human typing behaviour, handles dynamic content (with intelligent backspacing), and provides full playback control for scroll-triggered effects. All while ensuring screen reader accessibility.
<Typewriter>Hello world!</Typewriter>
Typewriter
is exclusive to Motion+ members. Motion+ is a one-time payment, lifetime membership that unlocks exclusive components, premium examples and access to a private Discord community.
Features
Natural animation: Typing speeds and variance emulate real-world behaviour.
Playback control: Easily play and pause animations, perfect for scroll-triggered animations.
Accessible: Correct ARIA labels for screen reader compatibility.
Reactive: Will animate with backspace and typing to the latest provided value.
Customisable: Control everything from typing speed and variance to cursor style and blink speed.
Install
First, add the Motion+ library to your project using your private token. You need to be a Motion+ member to generate a private token.
npm install https://api.motion.dev/registry\?package\=motion-plus\&version\=1.5.4\&token
Once installed, Typewriter
can be imported via motion-plus/react
:
import { Typewriter } from "motion-plus/react"
Usage
By passing a string as the Typewriter
child, it will animate that text in character by character.
<Typewriter>Hello world!</Typewriter>
Dynamic content
When the children
prop changes, Typewriter
will intelligently animate from the old text to the new text. By default, it backspaces character by character to the point of difference and then types out the new content.
By default, each character will be backspaced individually. Using the backspace
prop we can also backspace each word/special character:
<Typewriter backspace="word">{text}</Typewriter>
Or remove all the mismatching content immediately:
<Typewriter backspace="all">{text}</Typewriter>
Adjust speed
The animation will emulate "normal" real-world typing speeds, based on real research. It's also possible to set speed as "fast"
, "slow"
, or a custom interval (in milliseconds).
<Typewriter speed="slow">Hello world!</Typewriter>
By default, the typing speed will vary naturally per character, based on the type of content being "typed".
For example, typing will slow down while typing long words, while at the start/end of a word, when using punctuation, or when using uncommon character combinations.
This can be configured with the variance
prop. This is a 0
-1
factor applied to speed
, to create a range of speeds that we can randomly select between.
So for instance if we want no variance then we can set this to 0
.
<Typewriter variance={0}>Hello world!</Typewriter>
Or to have some variance it could be set to 0.5
:
<Typewriter variance={0.5}>Hello world!</Typewriter>
Cursor blink speed
Emulating real-world cursors, the cursor doesn't animate during an active typing animation.
Before or after typing, the cursor completes a blink cycle in 0.5
seconds. This can be adjusted using cursorBlinkDuration
:
<Typewriter cursorBlinkDuration={2}>Hello world!</Typewriter>
Playback control
Animations will play by default, but can be paused at any time by setting play={false}
.
This control makes it straightforward to, for instance, play animations only when they're within the viewport.
const ref = useRef(null) const isInView = useInView(ref) return ( <Typewriter ref={ref} play={isInView}> Hello world! </Typewriter> )
Props
as
Default: "span"
Set an element to render as.
<Typewriter as="h1">Hello world!</Typewriter>
speed
Default: "normal"
The typing speed of the animation.
Set as "slow"
, "normal"
or "fast"
to use a preset typing speed.
Or set as a duration, in milliseconds, to wait between keystrokes.
<Typewriter speed={90}>Hello world!</Typewriter>
variance
Default: "natural"
The amount of variance between the timing of each character.
By default, this is set to "natural"
. This will modify the timing between each character based on various factors:
Long words
Start/end of words
Punctuation
Uncommon character combinations
It can also be set to a factor where the speed can vary by the provided factor. For instance, setting to 0
will ensure a constant speed
:
// Constant 40ms between each character <Typewriter speed={40} variance={0}>
Whereas if we set this to 0.5
, then the speed can vary between speed
plus/minus variance x speed
:
// Between 20ms and 60ms for each character <Typewriter speed={40} variance={0.5}>
play
Default: true
Animation will pause when play
is false
. For example, this can be used to play animations only when elements appear on screen.
const ref = useRef(null) const isInView = useInView(ref) return ( <Typewriter ref={ref} play={isInView}> Hello world! </Typewriter> )
replace
Default: "type"
When the content changes, this sets the strategy for replacing the content.
"type"
: Type from the current content to the new content."all"
: Instantly delete existing content and start from scratch.
backspace
Default: "character"
When the content changes in replace: "type"
mode, Typewriter
will animate back to the closest matching value between the old and new values using emulated backspaces.
This behaviour can be configured using the backspace
prop:
"character"
: Backspace each character individually."word"
: Backspace each word (emulate option-backspace)."all"
: Delete everything instantly.
<Typewriter backspace="all"> {content} </Typewriter>
backspaceFactor
Default: 0.2
Configures the interval of each backspace with a factor that is relative to speed
. For instance, if speed
is set to 100
, then a factor of 0.1
will make each backspace 10ms.
Setting via a factor vs an absolute duration ensures you can adjust only speed
and the whole animation will scale appropriately.
cursorBlinkDuration
Default: 0.5
When the cursor is blinking, the blink animation will take this long (in seconds).
<Typewriter cursorBlinkDuration={1}>
cursorClassName
Apply this class to the cursor element for styling with CSS.
<Typewriter cursorClassName="cursor">
cursorStyle
Apply styles directly to the cursor element.
<Typewriter cursorStyle={{ backgroundColor: "red" }}>
textClassName
Apply this class to the inner text element for styling with CSS.
<Typewriter textClassName="typewriter-text">
textStyle
Apply styles directly to the cursor element.
<Typewriter textStyle={{ color: "red" }}>
onComplete
Callback to fire when the animation completes.
Typewriter
is a 1.3kb React component for creating realistic typewriter animations. It emulates natural human typing behaviour, handles dynamic content (with intelligent backspacing), and provides full playback control for scroll-triggered effects. All while ensuring screen reader accessibility.
<Typewriter>Hello world!</Typewriter>
Typewriter
is exclusive to Motion+ members. Motion+ is a one-time payment, lifetime membership that unlocks exclusive components, premium examples and access to a private Discord community.
Features
Natural animation: Typing speeds and variance emulate real-world behaviour.
Playback control: Easily play and pause animations, perfect for scroll-triggered animations.
Accessible: Correct ARIA labels for screen reader compatibility.
Reactive: Will animate with backspace and typing to the latest provided value.
Customisable: Control everything from typing speed and variance to cursor style and blink speed.
Install
First, add the Motion+ library to your project using your private token. You need to be a Motion+ member to generate a private token.
npm install https://api.motion.dev/registry\?package\=motion-plus\&version\=1.5.4\&token
Once installed, Typewriter
can be imported via motion-plus/react
:
import { Typewriter } from "motion-plus/react"
Usage
By passing a string as the Typewriter
child, it will animate that text in character by character.
<Typewriter>Hello world!</Typewriter>
Dynamic content
When the children
prop changes, Typewriter
will intelligently animate from the old text to the new text. By default, it backspaces character by character to the point of difference and then types out the new content.
By default, each character will be backspaced individually. Using the backspace
prop we can also backspace each word/special character:
<Typewriter backspace="word">{text}</Typewriter>
Or remove all the mismatching content immediately:
<Typewriter backspace="all">{text}</Typewriter>
Adjust speed
The animation will emulate "normal" real-world typing speeds, based on real research. It's also possible to set speed as "fast"
, "slow"
, or a custom interval (in milliseconds).
<Typewriter speed="slow">Hello world!</Typewriter>
By default, the typing speed will vary naturally per character, based on the type of content being "typed".
For example, typing will slow down while typing long words, while at the start/end of a word, when using punctuation, or when using uncommon character combinations.
This can be configured with the variance
prop. This is a 0
-1
factor applied to speed
, to create a range of speeds that we can randomly select between.
So for instance if we want no variance then we can set this to 0
.
<Typewriter variance={0}>Hello world!</Typewriter>
Or to have some variance it could be set to 0.5
:
<Typewriter variance={0.5}>Hello world!</Typewriter>
Cursor blink speed
Emulating real-world cursors, the cursor doesn't animate during an active typing animation.
Before or after typing, the cursor completes a blink cycle in 0.5
seconds. This can be adjusted using cursorBlinkDuration
:
<Typewriter cursorBlinkDuration={2}>Hello world!</Typewriter>
Playback control
Animations will play by default, but can be paused at any time by setting play={false}
.
This control makes it straightforward to, for instance, play animations only when they're within the viewport.
const ref = useRef(null) const isInView = useInView(ref) return ( <Typewriter ref={ref} play={isInView}> Hello world! </Typewriter> )
Props
as
Default: "span"
Set an element to render as.
<Typewriter as="h1">Hello world!</Typewriter>
speed
Default: "normal"
The typing speed of the animation.
Set as "slow"
, "normal"
or "fast"
to use a preset typing speed.
Or set as a duration, in milliseconds, to wait between keystrokes.
<Typewriter speed={90}>Hello world!</Typewriter>
variance
Default: "natural"
The amount of variance between the timing of each character.
By default, this is set to "natural"
. This will modify the timing between each character based on various factors:
Long words
Start/end of words
Punctuation
Uncommon character combinations
It can also be set to a factor where the speed can vary by the provided factor. For instance, setting to 0
will ensure a constant speed
:
// Constant 40ms between each character <Typewriter speed={40} variance={0}>
Whereas if we set this to 0.5
, then the speed can vary between speed
plus/minus variance x speed
:
// Between 20ms and 60ms for each character <Typewriter speed={40} variance={0.5}>
play
Default: true
Animation will pause when play
is false
. For example, this can be used to play animations only when elements appear on screen.
const ref = useRef(null) const isInView = useInView(ref) return ( <Typewriter ref={ref} play={isInView}> Hello world! </Typewriter> )
replace
Default: "type"
When the content changes, this sets the strategy for replacing the content.
"type"
: Type from the current content to the new content."all"
: Instantly delete existing content and start from scratch.
backspace
Default: "character"
When the content changes in replace: "type"
mode, Typewriter
will animate back to the closest matching value between the old and new values using emulated backspaces.
This behaviour can be configured using the backspace
prop:
"character"
: Backspace each character individually."word"
: Backspace each word (emulate option-backspace)."all"
: Delete everything instantly.
<Typewriter backspace="all"> {content} </Typewriter>
backspaceFactor
Default: 0.2
Configures the interval of each backspace with a factor that is relative to speed
. For instance, if speed
is set to 100
, then a factor of 0.1
will make each backspace 10ms.
Setting via a factor vs an absolute duration ensures you can adjust only speed
and the whole animation will scale appropriately.
cursorBlinkDuration
Default: 0.5
When the cursor is blinking, the blink animation will take this long (in seconds).
<Typewriter cursorBlinkDuration={1}>
cursorClassName
Apply this class to the cursor element for styling with CSS.
<Typewriter cursorClassName="cursor">
cursorStyle
Apply styles directly to the cursor element.
<Typewriter cursorStyle={{ backgroundColor: "red" }}>
textClassName
Apply this class to the inner text element for styling with CSS.
<Typewriter textClassName="typewriter-text">
textStyle
Apply styles directly to the cursor element.
<Typewriter textStyle={{ color: "red" }}>
onComplete
Callback to fire when the animation completes.