2 min read
The little terminal that types itself
How the animated terminal on my home page works — a tiny state machine.
If you've seen the home page, you've met the terminal that types commands on its own. It's one of my favourite kinds of code: small, self-contained, and a bit delightful.
The idea
It's just a loop. For each command, we:
- Type it out one character at a time.
- Print its "output".
- Pause, then move to the next command.
The core loop
The whole thing is a recursive async loop guarded by an alive flag so it
tears down cleanly:
useEffect(() => {
let alive = true;
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
const run = async () => {
let i = 0;
while (alive) {
const c = commands[i % commands.length];
for (let k = 1; k <= c.cmd.length && alive; k++) {
setTyping(c.cmd.slice(0, k));
await wait(38 + Math.random() * 55); // jitter = human feel
}
// ...print output, pause, i++
}
};
run();
return () => { alive = false; };
}, [commands]);The details that sell it
- Jittered timing so it doesn't feel mechanical.
- A blinking block cursor made of a single
<span>and one keyframe. - It honours
prefers-reduced-motionby rendering a static frame instead.
Small touches, but together they make a rectangle of text feel alive.