TypeScript · Playwright · Bun

Type like a human, not a bot.

Realistic human typing simulation for TypeScript and Playwright. Variable timing, neighbor-key errors, swaps, backspacing, fatigue, and bigram speedups.

$ bun add humantyping-ts
localhost:5173 — Playwright
HumanTypingTS typing demo

Real output from the library — pauses, typos, corrections, and all.

The bot test you've been failing

Default page.fill() dumps the entire string in one frame. Real keyboards don't do that.

Before: Instant string dump

// page.fill(input, "Hello world")
Hello world 
// One frame, no variance, no errors.
// Cloudflare, reCAPTCHA, and
// behavioral fingerprinters notice.

After: Realistic keystrokes

// await typer.type(input, "Hello world")
Hello world 
// Per-key delays from a Markov model,
// occasional typos with backspace
// corrections, and bigram speedups.

Drop it into any Playwright script

type-realistically.ts
import { chromium } from "playwright"; import { HumanTyper } from "humantyping-ts"; const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto("https://example.com"); const typer = new HumanTyper({ wpm: 70, layout: "qwerty" }); await typer.type(page.locator("input[name='q']"), "realistic typing!");

What makes it feel human

Markov-chain timing

Per-keystroke delays sampled from a normal distribution around your target WPM, with std deviation that compounds realistically.

🎞

Neighbor-key errors

Mistypes are biased toward physically adjacent keys on QWERTY/AZERTY/Dvorak. Some get noticed and corrected with backspace, others don't.

🙋

Word difficulty

Common bigrams speed up. Complex words and composed accents slow down. The model gets tired over long passages.

🚀

Playwright-first

Works with locators, element handles, or any object exposing a Playwright-compatible keyboard interface.

🧮

Headless simulation

Use MarkovTyper + runMonteCarlo to simulate timings without a browser. Useful for tests and analytics.

📦

Zero runtime deps

Playwright is an optional peer dependency. Pure-simulation users pay nothing for browser machinery.

Ship typing your bot detector won't catch