Animated terminal
Also called terminal animation, typing terminal, or terminal window
A terminal window on a landing page that types out commands and prints their output line by line, to show how a developer tool is used.
import { useEffect, useState } from 'react';
import { useReducedMotion } from 'motion/react';
type Line = { type: 'command' | 'output'; text: string };
const SCRIPT: Line[] = [
{
type: 'command',
text: 'npm create vite@latest my-app -- --template react-ts'
},
{ type: 'output', text: 'Scaffolding project in ./my-app...' },
{ type: 'output', text: 'Done.' },
{ type: 'command', text: 'cd my-app && npm install' },
{ type: 'output', text: 'added 192 packages in 6s' },
{ type: 'command', text: 'npm run dev' },
{ type: 'output', text: '➜ Local: http://localhost:5173/' }
];
const TYPE_MS = 50; // per character of a command
const OUTPUT_MS = 120; // per output line
const HOLD_MS = 4000; // finished screen, before it starts over
export function AnimatedTerminal() {
const reduceMotion = useReducedMotion();
// How many lines are done, and how many characters of the next one are typed.
const [{ line, chars }, setStep] = useState({ line: 0, chars: 0 });
const current = SCRIPT[line];
useEffect(() => {
if (reduceMotion) return;
const typing = current?.type === 'command' && chars < current.text.length;
const delay = !current ? HOLD_MS : typing ? TYPE_MS : OUTPUT_MS;
const id = setTimeout(() => {
if (!current) setStep({ line: 0, chars: 0 });
else if (typing) setStep({ line, chars: chars + 1 });
else setStep({ line: line + 1, chars: 0 });
}, delay);
return () => clearTimeout(id);
}, [reduceMotion, current, line, chars]);
const shown = reduceMotion ? SCRIPT.length : line;
return (
<div className='w-[560px] overflow-hidden rounded-xl bg-neutral-950 font-mono text-sm text-neutral-200 shadow-xl'>
<div
aria-hidden='true'
className='flex gap-1.5 px-4 py-3 *:size-3 *:rounded-full *:bg-neutral-700'
>
<i />
<i />
<i />
</div>
{/* Screen readers get the whole transcript at once. */}
<p className='sr-only'>{SCRIPT.map((step) => step.text).join('\n')}</p>
<div
aria-hidden='true'
className='min-h-56 px-4 pb-4 leading-6 whitespace-pre-wrap'
>
{SCRIPT.slice(0, shown).map((step, i) => (
<div
key={i}
className={step.type === 'output' ? 'text-neutral-400' : ''}
>
{step.type === 'command' && (
<span className='text-green-400'>$ </span>
)}
{step.text}
</div>
))}
{current?.type === 'command' && !reduceMotion && (
<div>
<span className='text-green-400'>$ </span>
{current.text.slice(0, chars)}
<span className='animate-pulse'>▋</span>
</div>
)}
</div>
</div>
);
}Add an animated terminal to the docs hero: a 560px wide dark window with 12px corners, three gray dots in the title bar, and 14px monospace text. It types `npm create vite@latest my-app` at 50ms per character behind a blinking block cursor, prints the output lines 120ms apart, then types `cd my-app`, `npm install`, and `npm run dev` the same way, ending on the local URL in blue. Hold the finished screen for 4s, then restart. Pause while off-screen and show the full transcript under prefers-reduced-motion.
Paste into Layerwise or any AI coding tool.
What is Animated terminal?
An animated terminal draws a small window with a dark background, three dots in the title bar, and monospaced text. It types a command one character at a time behind a blinking cursor, pauses, prints the output a line at a time, and moves on to the next command. Developer tools use it in heroes and docs to show install and setup steps without a video.
Build it from a script: a list of steps, each a command to type or output to print, with a delay for each. Type commands at about 40 to 70ms per character, print output lines about 100ms apart, and hold the final screen for a few seconds before looping, or stop at the end so people can read and copy it.
Use real commands that work when pasted. Keep the full text in the page so it can be selected, searched, and read by screen readers, and animate only how it is revealed. Pause when the terminal scrolls out of view, and under reduced motion show the finished transcript right away. A copy button next to the first command saves people from selecting text.
Often confused with
- Typewriter effect
- A typewriter effect reveals any text one character at a time. An animated terminal uses it inside a terminal window and adds prompts, command output, and pauses.
Related terms
All termsTypewriter effect
A text animation that reveals a line one character at a time, as if someone were typing it, usually with a blinking caret at the end.
Stagger
Animating a group of items one after another with a small delay between each, so they arrive as a cascade.
Hero section
The large first section at the top of a landing page, with a headline, a short subhead, a call to action, and a visual.
Looping animation
An animation that plays more than once, either a set number of times or forever, set in CSS with animation-iteration-count.
Build it with Layerwise
Describe your app, watch it run in a live preview, and publish it with a database, storage, and sign-in built in.