bot-signal

Live demo — everything runs in your browser

Is your browser
being scanned…

bot-signal (npm package `bot-signal`) spots headless browsers, automation frameworks, and scripted interaction — in the browser and on the server. This page runs the real library against you.

npm install bot-signal

TypeScript · ESM + CJS · browser/server entry points · one dependency · MIT

Verdict Scanning… Running instant checks
Instant checks
Flagged
Behavioral score
not run

Layer 1 · synchronous

Instant detection

detectInstantClient(window) inspects the environment in a single pass — WebDriver flags, automation artifacts, rendering, and window geometry. Signals roll up into a weighted suspicionScore.

Pretend to be a bot:

Layer 2 · over time

Behavioral detection

createBehavioralClientDetector() watches how the pointer, wheel, and keyboard behave. Humans are noisy; scripts are not. Touch taps, keyboard clicks, and key auto-repeat are recognized — they never count against you.

What the detector sees

move, scroll, click, type — anywhere on the page
0mouse moves
0scrolls
0keys
0clicks
0synthetic
Suspicion score 0.000
0.55 threshold
0 · human1 · automated

    Layer 3 · Node

    Server-side scoring

    detectServerClientAsync() runs in Node — GeoIP, datacenter ranges, AbuseIPDB, iCloud Private Relay, and TLS fingerprints, all offline. This simulator uses the library's real weights and formula: score = 1 − Π(1 − wᵢ).

      Suspicion score 0.000
      0.50 threshold
      0 · human1 · automated
      Equivalent request context

      Ship it

      Quick start

      One package, three layers. Import from the root, or use the /browser and /server entry points.

      Browser — block on load

      import { isHuman } from "bot-signal";
      
      const result = detectInstantClient(window);
      
      if (!result.isLegitClient) {
        location.href = "/blocked";
      }

      Behavioral — observe & score

      import { createBehavioralClientDetector } from "bot-signal";
      
      const result = await createBehavioralClientDetector({ context: window })
        .observe(10_000);
      
      if (!result.isLegitClient) challenge();

      Server — score a request

      import { detectServerClientAsync } from "bot-signal/server";
      
      const result = await detectServerClientAsync({
        clientIp: req.ip,
        clientTimezone: req.headers["x-timezone"],
        userAgent: req.headers["user-agent"],
        tlsFingerprint: req.headers["x-ja3-hash"],
      });
      
      if (!result.isLegitClient) res.status(403).end();