Bot detection has learned to spot automated browsers by how predictable they are: a click exactly 500ms after the page loads, a mouse that travels in a straight line, every keystroke at the same interval, mechanical scrolling, and never a mistake or a moment of hesitation. I built definitely-not-a-robot, a wrapper around Puppeteer, to put the imperfection back.

Predictability was the problem
That predictability hurts legitimate work as much as anything else. Testing tools get blocked on production sites, research scraping runs into endless CAPTCHAs, QA automation fails on bot checks and monitoring tools get their IPs banned, so data collection becomes unreliable.
Hiding the automation only goes so far, so the package also makes it behave less like a machine: deliberate randomness in timing, curved movement and small pauses, so the browser acts the way a person does.
Movement and timing
The base is puppeteer-extra with its stealth plugin. The wrapper is written in TypeScript and bundled to CommonJS with
esbuild, with each behaviour in its own utility:
- Mouse paths follow Bezier curves, split into segments with jitter and natural acceleration and deceleration.
- Typing delays grow with the distance between character codes, at 40 WPM by default, with a 200ms pause after
.,!or?. - Clicks wait a random 50 to 150ms, with optional hesitation before important ones.
- Idle jitter moves the mouse 3 to 95 pixels and back again, like a resting hand, with configurable intensity and count.
- Debug mode draws the mouse path in red.
The API stays small, and every method returns a promise. Here it drives the shadcn/ui site, typing quickly in one field and slowly in another:
// From a clone of the GitHub repository (it isn't on npm)
import HumanBrowser from "./npm-definitely-not-a-robot/src/HumanBrowser";
const browser = new HumanBrowser();
await browser.launch({ headless: false });
await browser.navigate("https://ui.shadcn.com");
// Search with natural movement and typing
await browser.humanMove('input[type="search"]', {
hesitationBeforeClick: true,
debug: true, // Shows red path
});
await browser.jitterMouse({ jitterCount: 3 });
await browser.humanType("Hello World", 86); // 86 WPM
// Navigate with pauses
await browser.wait(300, 500);
await browser.humanMove('button[aria-label="Select a team"]');
// Careful typing for important fields
await browser.humanType("Monster", 30); // Slow 30 WPM
await browser.close();
The source and working examples are on GitHub.
What mattered while building it
Randomness is the key. The difference between a bot and a person is unpredictability. People don't move in straight lines, their typing speed varies from key to key and their hands drift when idle.
Seeing the path mattered. The red debug trace showed exactly how the mouse moved, so I could check the curves looked natural, spot mechanical patterns at a glance and tune the parameters by eye.
Simple beat clever. Plain randomisation worked better than a complex ML model would have: Bezier curves for movement, varied delays for typing and basic jitter for idle time.
Built for legitimate automation
The package is for testing, research, monitoring and accessibility: running QA on a production site without tripping bot detection, collecting public data for research and building automation that doesn't break. The README is blunt about the rest: "Beep Boop. I don't condone this behaviour." Sometimes, though, you need to test your own production site without getting blocked.
Research and sources
Checked 2026-10-18. Next review: 2027-04-18. Listings and availability can change.
dougwithseismic/npm-definitely-not-a-robot
GitHub · Checked 2026-10-18 · Primary source
The package's source, README and demo GIF: a Puppeteer wrapper with Bezier mouse movement, WPM-based typing, jitter and a debug path, built on puppeteer-extra's stealth plugin.
Puppeteer
Google Chrome · Checked 2026-10-18 · Primary source
Puppeteer is the browser automation library the package wraps.
puppeteer-extra-plugin-stealth
puppeteer-extra · Checked 2026-10-18 · Primary source
The stealth plugin for puppeteer-extra, which the package builds on to avoid common automation fingerprints.
esbuild
esbuild · Checked 2026-10-18 · Primary source
esbuild is the bundler that compiles the package's TypeScript.


