isbot
Use this skill for isbot v5 (isbot on npm, folder name is-bot): recognise self-identifying bots, crawlers, and spiders from a User-Agent string.
Package: isbot. Repo: omrilotan/isbot. Tester: isbot.js.org. Snapshot 5.2.1.
Workflow
- Inspect the local surface:
- Installed
isbot version (bun pm ls isbot). Target v5.2+ for camelCase isBot names.
- Import style: named
isBot (preferred) vs legacy isbot. No default export.
- Call site: Fetch
Headers, Node IncomingMessage, Express/Fastify/Hono/Elysia, browser navigator.userAgent.
- Goal: analytics exclusion, cache preference, skip pixels — not stealth-bot blocking or SEO cloaking.
- Custom lists:
createIsBotFromList / createIsBot vs default isBot.
- Refresh docs when versions drift or work touches custom patterns, naive fallback, or major-version imports. Start from source-map.md.
- Route deeper detail:
- Install, engines, exports, null/empty handling: setup-core.md.
- Named API, naive pattern,
getPattern cache: api.md.
- Custom regex / list filters (Lighthouse, extras): custom-patterns.md.
- Framework recipes, analytics, cache, pixels: integrations.md.
- What it cannot do, anti-patterns, v3–v6: pitfalls-migration.md.
- Prefer
bun / bunx in command examples.
- Verify with typecheck plus UA fixtures (known bot, known browser, missing header, custom list).
Library Decision Tree
Need to flag self-declared crawlers / HTTP clients / preview bots from User-Agent?
→ isbot (this skill). Prefer isBot(ua).
Need to verify Googlebot / Bingbot identity (not spoofed UA)?
→ isBot as a cheap prefilter, then reverse DNS (or provider IP lists). Never whitelist on UA alone.
Need to catch stealth scrapers, residential-proxy bots, or browser-impersonating clients?
→ isbot will not help. Use rate limits, WAF, TLS/JA3, CAPTCHA, behaviour — not this package.
Need a tiny/fast heuristic and can accept false positives (e.g. "http" in UA)?
→ isBotNaive, or accept getPattern() fallback on engines without lookbehind.
Need to treat Lighthouse / Cypress as humans for product analytics?
→ createIsBotFromList after removing those pattern parts. Do not fork the default isBot in-place.
Core Judgment
- Scope is honest User-Agents only. isbot matches "good bots" that volunteer a distinctive UA. It does not detect disguised scrapers.
- Do not cloak. Do not serve different primary HTML to Googlebot than to users. Allowed: skip analytics pixels, prefer cache, flag pageviews.
- Do not whitelist on UA. Confirm crawler identity with reverse DNS or official IP ranges.
- Named camelCase API (
isBot, createIsBotFromList, findBotMatch, …). Legacy isbot / isbotMatch still work in 5.2.x; they are scheduled to drop in v6.
isBot(null | undefined | "") is false. Pass header values through as-is. Missing UA is not a bot.
- Hot path =
isBot only. findBotMatches / findBotPatterns compile one RegExp per list part — debug/audit, not every request.
getPattern() is lazy and cached. Engines that reject lookbehind fall back to the naive pattern (~1% false positive, ~75% bot coverage).
list entries are regex fragments, not literal strings. Escape custom tokens before createIsBotFromList.
- HTTP clients (axios, undici, Postman, Cypress, curl-like UAs) typically match as bots. That is intended.
Verification
Prefer repository-owned commands. Cover the relevant subset:
bun pm ls isbot — confirm 5.x (and 5.2+ if using camelCase-only guidance).
- Typecheck:
isBot(headers.get("User-Agent")) accepts string | null.
- Fixtures: Googlebot →
true; desktop Chrome → false; undefined/null/"" → false.
- Custom list: extra token matches; removed Lighthouse patterns no longer match those UAs.
- Debug helpers:
findBotMatch / findBotPattern explain a surprising true.
- If using reverse DNS for claimed Googlebot/Bingbot, assert both UA match and verified hostname.
Report which checks ran, which did not, and version/export-name assumptions that remain.
1---2name: is-bot3description: Build, review, debug, migrate, or plan User-Agent bot/crawler/spider detection with the isbot npm package (v5). Use for isbot, is-bot, isBot, isBotNaive, getPattern, list, createIsBot, createIsBotFromList, findBotMatch, findBotMatches, findBotPattern, findBotPatterns, Googlebot, Lighthouse, crawlers, spiders, analytics bot filtering, reverse-dns-lookup verification, and v3/v4/v5/v6 export migrations.4---56# isbot78Use this skill for **isbot v5** (`isbot` on npm, folder name `is-bot`): recognise self-identifying bots, crawlers, and spiders from a User-Agent string.910Package: [`isbot`](https://www.npmjs.com/package/isbot). Repo: [omrilotan/isbot](https://github.com/omrilotan/isbot). Tester: [isbot.js.org](https://isbot.js.org). Snapshot **5.2.1**.1112## Workflow13141. Inspect the local surface:15 - Installed `isbot` version (`bun pm ls isbot`). Target **v5.2+** for camelCase `isBot` names.16 - Import style: named `isBot` (preferred) vs legacy `isbot`. No default export.17 - Call site: Fetch `Headers`, Node `IncomingMessage`, Express/Fastify/Hono/Elysia, browser `navigator.userAgent`.18 - Goal: analytics exclusion, cache preference, skip pixels — **not** stealth-bot blocking or SEO cloaking.19 - Custom lists: `createIsBotFromList` / `createIsBot` vs default `isBot`.202. Refresh docs when versions drift or work touches custom patterns, naive fallback, or major-version imports. Start from [source-map.md](references/source-map.md).213. Route deeper detail:22 - Install, engines, exports, null/empty handling: [setup-core.md](references/setup-core.md).23 - Named API, naive pattern, `getPattern` cache: [api.md](references/api.md).24 - Custom regex / list filters (Lighthouse, extras): [custom-patterns.md](references/custom-patterns.md).25 - Framework recipes, analytics, cache, pixels: [integrations.md](references/integrations.md).26 - What it cannot do, anti-patterns, v3–v6: [pitfalls-migration.md](references/pitfalls-migration.md).274. Prefer **`bun` / `bunx`** in command examples.285. Verify with typecheck plus UA fixtures (known bot, known browser, missing header, custom list).2930## Library Decision Tree3132```33Need to flag self-declared crawlers / HTTP clients / preview bots from User-Agent?34 → isbot (this skill). Prefer isBot(ua).3536Need to verify Googlebot / Bingbot identity (not spoofed UA)?37 → isBot as a cheap prefilter, then reverse DNS (or provider IP lists). Never whitelist on UA alone.3839Need to catch stealth scrapers, residential-proxy bots, or browser-impersonating clients?40 → isbot will not help. Use rate limits, WAF, TLS/JA3, CAPTCHA, behaviour — not this package.4142Need a tiny/fast heuristic and can accept false positives (e.g. "http" in UA)?43 → isBotNaive, or accept getPattern() fallback on engines without lookbehind.4445Need to treat Lighthouse / Cypress as humans for product analytics?46 → createIsBotFromList after removing those pattern parts. Do not fork the default isBot in-place.47```4849## Core Judgment5051- **Scope is honest User-Agents only.** isbot matches "good bots" that volunteer a distinctive UA. It does **not** detect disguised scrapers.52- **Do not cloak.** Do not serve different primary HTML to Googlebot than to users. Allowed: skip analytics pixels, prefer cache, flag pageviews.53- **Do not whitelist on UA.** Confirm crawler identity with reverse DNS or official IP ranges.54- **Named camelCase API** (`isBot`, `createIsBotFromList`, `findBotMatch`, …). Legacy `isbot` / `isbotMatch` still work in 5.2.x; they are scheduled to drop in **v6**.55- **`isBot(null | undefined | "")` is `false`.** Pass header values through as-is. Missing UA is not a bot.56- **Hot path = `isBot` only.** `findBotMatches` / `findBotPatterns` compile one `RegExp` per list part — debug/audit, not every request.57- **`getPattern()` is lazy and cached.** Engines that reject lookbehind fall back to the naive pattern (~1% false positive, ~75% bot coverage).58- **`list` entries are regex fragments**, not literal strings. Escape custom tokens before `createIsBotFromList`.59- HTTP clients (**axios**, **undici**, **Postman**, **Cypress**, curl-like UAs) typically match as bots. That is intended.6061## Verification6263Prefer repository-owned commands. Cover the relevant subset:6465- `bun pm ls isbot` — confirm **5.x** (and 5.2+ if using camelCase-only guidance).66- Typecheck: `isBot(headers.get("User-Agent"))` accepts `string | null`.67- Fixtures: Googlebot → `true`; desktop Chrome → `false`; `undefined`/`null`/`""` → `false`.68- Custom list: extra token matches; removed Lighthouse patterns no longer match those UAs.69- Debug helpers: `findBotMatch` / `findBotPattern` explain a surprising `true`.70- If using reverse DNS for claimed Googlebot/Bingbot, assert both UA match **and** verified hostname.7172Report which checks ran, which did not, and version/export-name assumptions that remain.