> ## Documentation Index
> Fetch the complete documentation index at: https://withseismic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# definitely-not-a-robot: Humanizing Browser Automation

> How we built an npm package that makes automated browsers indistinguishable from human users

<script type="application/ld+json">
  {`{
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "definitely-not-a-robot: Humanizing Browser Automation",
    "description": "Case study of an npm package that makes automated browsers indistinguishable from human users",
    "url": "https://withseismic.com/case-studies/definitely-not-a-robot",
    "author": {
      "@type": "Organization",
      "name": "WithSeismic"
    },
    "publisher": {
      "@type": "Organization",
      "name": "WithSeismic"
    },
    "about": {
      "@type": "SoftwareApplication",
      "name": "definitely-not-a-robot",
      "applicationCategory": "DeveloperApplication",
      "description": "NPM package for human-like browser automation"
    }
    }`}
</script>

<img src="https://mintcdn.com/withseismic/fG8BLsvyEuMKKSDK/images/definitely-not-a-robot.gif?s=6b06ea5527be7ad37994a07ee39ec354" alt="Definitely Not A Robot Demo" width="1234" height="676" data-path="images/definitely-not-a-robot.gif" />

## How It Started

Web automation has become a cat-and-mouse game. Modern bot detection systems have learned to identify automated browsers through predictable patterns: bots click exactly 500ms after page load, mouse travels in straight lines to targets, every keystroke at identical intervals, mechanical scrolling, and zero mistakes or hesitation.

This made legitimate automation tasks increasingly difficult. Testing tools got blocked on production sites. Web scraping for research hit endless CAPTCHAs. QA automation failed due to bot detection. Monitoring tools got IP banned. Data collection became unreliable.

## Building the Solution

I built `definitely-not-a-robot`, a Puppeteer wrapper that embraces human imperfection as a feature. By introducing deliberate randomness and natural movement patterns, it makes automated browsers virtually indistinguishable from human users.

The package leverages puppeteer-extra with StealthPlugin and adds layers of human-like behaviors: Bezier curve mouse movements that arc naturally like a human hand, variable typing speeds based on ASCII key distances, random micro-movements during idle time, natural hesitation before important clicks, and debug visualization to see exactly how the "human" moves.

## The Technical Build

### Core Architecture

**Language**: TypeScript for type safety
**Bundler**: ESBuild for fast compilation
**Base**: Puppeteer-extra with StealthPlugin
**Output**: CommonJS for broad compatibility

### Key Implementations

#### Bezier Mouse Movement Algorithm

```typescript theme={null}
// Splits long movements into segments with jitter
const distance = calculateDistance(start, end);
const segments = Math.max(2, Math.min(50, Math.floor(distance / 10)));

// Natural acceleration/deceleration
const speed = 0.03 + distance * 0.001;
const acceleration = 0.002;

// Bezier control points for curved paths
const ctrlPt1 = start + Math.random() * (end - start) * 0.5;
const ctrlPt2 = end - Math.random() * (end - start) * 0.5;
```

#### ASCII-Based Typing Delays

```typescript theme={null}
// Larger key distance = longer delay
const diff = Math.abs(text.charCodeAt(i) - text.charCodeAt(i - 1));
const delay = averageDelayPerChar + diff * 2;

// Pause after punctuation
if ([".", "!", "?"].includes(char)) {
  delay += 200; // Natural thinking pause
}
```

#### Jitter Movement System

* 3-95 pixel random movements
* Returns to original position
* Simulates idle hand tremor
* Configurable intensity and count

### API Design

```typescript theme={null}
const browser = new HumanBrowser();

// All methods return promises for chaining
await browser.launch({ headless: false });
await browser.navigate("https://example.com");
await browser.humanMove("#button", {
  hesitationBeforeClick: true,
});
await browser.humanType("Hello World", 100); // WPM
await browser.jitterMouse({ jitterCount: 3 });
await browser.wait(1000, 5000); // Random delay
```

## What We Built

The package includes Bezier curve paths instead of straight lines, 50-150ms random click delays for natural hesitation, WPM-based typing with variable speeds (default 40 WPM), debug mode showing red path visualization, and zero dependencies beyond the Puppeteer ecosystem.

## The Results

The package is now used for QA testing - running tests on production without triggering bot detection. Web scraping teams use it for collecting public data for research and analysis. Automation developers build reliable workflows that don't break. Monitoring tools track competitor sites without getting banned.

It's published on npm as `definitely-not-a-robot` with a GitHub repository containing working examples, a demo automation of shadcn/ui interface, and clear documentation with TypeScript types.

## What We Learned

**Randomness is the key.** The difference between bot and human is unpredictability. Humans don't move in straight lines. Typing speed varies based on key distance. Everyone has idle hand movements. Mistakes and corrections are natural.

**Debug visualization matters.** The red path tracing was crucial for development. We could see exactly how the mouse moves, verify Bezier curves look natural, spot mechanical patterns instantly, and tune parameters visually.

**Simplicity wins.** Rather than complex ML models, simple randomization worked better. Bezier curves for natural arcs, normal distribution for delays, ASCII distance for typing variance, basic jitter for idle movement.

What made it work was mathematical foundations (Bezier curves and easing functions), observation of how humans actually move and type, debug-first development with visual feedback, modular design with separate utilities for each behavior, and TypeScript catching edge cases during development.

The project proved simple randomization can defeat bot detection, showed legitimate use cases need human-like automation, demonstrated the importance of imperfection in automation, and set a template for ethical automation tools.

***

## Open Source

<Card title="definitely-not-a-robot on GitHub" icon="github" href="https://github.com/dougwithseismic/npm-definitely-not-a-robot">
  View source code and contribute
</Card>

## Technologies Used

<CardGroup cols={3}>
  <Card title="TypeScript" icon="code">
    Type-safe development
  </Card>

  <Card title="Puppeteer" icon="browser">
    Browser automation
  </Card>

  <Card title="ESBuild" icon="bolt">
    Fast bundling
  </Card>

  <Card title="Stealth Plugin" icon="user-secret">
    Bot evasion
  </Card>

  <Card title="Bezier Curves" icon="wave">
    Natural movement
  </Card>

  <Card title="Canvas API" icon="paint-brush">
    Debug visualization
  </Card>
</CardGroup>

***

## Code Example

Here's how the package handles a typical automation flow:

```typescript theme={null}
import HumanBrowser from "definitely-not-a-robot";

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();
```

***

## Ethical Note

While this tool can bypass bot detection, it's designed for legitimate use cases: testing, research, monitoring, and accessibility. The project includes clear disclaimers about responsible use and explicitly discourages malicious applications.

As we note in the README: "Beep Boop. We don't condone this behaviour." — But sometimes you need to test your production site without getting blocked.

***

## Frequently Asked Questions

<AccordionGroup>
  <Accordion title="How does this package make automation look human?">
    It introduces deliberate imperfection through Bezier curve mouse movements, variable typing speeds based on key distances, random micro-movements during idle time, natural hesitation before clicks, and randomized delays. This contrasts with typical automation that moves in straight lines and acts with mechanical precision.
  </Accordion>

  <Accordion title="What makes the Bezier curve mouse movement effective?">
    Instead of straight-line robot movements, the package calculates curved paths that arc naturally like a human hand would move. The algorithm splits long movements into segments with jitter, applies natural acceleration and deceleration, and uses control points to create realistic curved paths that vary each time.
  </Accordion>

  <Accordion title="How does the typing simulation work?">
    Typing delays are calculated based on ASCII character distances - larger key distances result in longer delays, just like real typing. The system adds natural pauses after punctuation marks and allows you to set WPM (words per minute) rates that match human typing speeds, typically 40 WPM by default.
  </Accordion>

  <Accordion title="What is the debug mode and why is it important?">
    Debug mode shows red path visualization so you can see exactly how the mouse moves across the screen. This was crucial during development to verify that Bezier curves look natural, spot mechanical patterns instantly, and tune parameters visually. It helps developers optimize their automation to look truly human.
  </Accordion>

  <Accordion title="What are legitimate use cases for this tool?">
    The package is designed for QA testing on production sites without triggering bot detection, web scraping for research and data collection, building reliable automation workflows, monitoring competitor sites, and accessibility testing. It's built for legitimate automation needs that get blocked by overzealous bot detection.
  </Accordion>

  <Accordion title="How does it compare to regular Puppeteer automation?">
    Regular Puppeteer automation moves in straight lines, clicks at exact intervals, types at consistent speeds, and acts with mechanical precision. This package adds human unpredictability - curved mouse paths, variable delays, natural hesitation, idle movements, and typing patterns based on key distances.
  </Accordion>

  <Accordion title="What technical foundation makes the human simulation work?">
    The package uses mathematical foundations like Bezier curves and easing functions, observation of actual human movement patterns, debug-first development with visual feedback, modular design for different behaviors, and TypeScript for catching edge cases. Simple randomization proved more effective than complex ML models.
  </Accordion>

  <Accordion title="How does the jitter movement system work?">
    The jitter system creates 3-95 pixel random movements that return to the original position, simulating the natural hand tremor humans have during idle time. It's configurable for intensity and count, adding another layer of human-like behavior that bots typically lack.
  </Accordion>

  <Accordion title="What makes this approach better than existing bot detection evasion?">
    Instead of trying to hide automation signatures, this package embraces human imperfection as a feature. It focuses on making the automation genuinely behave like a human rather than just masking bot fingerprints. The mathematical approach to movement and timing patterns creates convincing human simulation.
  </Accordion>

  <Accordion title="How can developers get started with this package?">
    Install via npm as 'definitely-not-a-robot', import the HumanBrowser class, and use methods like humanMove(), humanType(), and jitterMouse(). The package includes TypeScript types, clear documentation, working examples, and a demo automation of shadcn/ui interface. The GitHub repository has complete implementation details.
  </Accordion>
</AccordionGroup>
