AntiBrow recipes
August 28, 2026 · View on GitHub
Task-level site adapters for AntiBrow. One file per
command: an agent asks for reddit/hot and gets structured JSON back, instead of
a browser handle and a scraping problem.
npm install -g anti-detect-browser
anti-detect-browser recipe update
anti-detect-browser recipe run reddit/hot --temporary --json
anti-detect-browser recipe run reddit/hot --profile shopper-01 --jq '.items[].title'
Platforms covered today
| commands | |
|---|---|
| Search | google/search · duckduckgo/search |
| Marketplaces | amazon/search · walmart/search |
| Social & community | reddit/hot reddit/search reddit/comments · x/timeline · hackernews/top hackernews/item |
| Publishing | medium/tag |
| Developer | github/repo · pypi/package · npm/package |
| Listings & jobs | yelp/search · indeed/jobs |
| Identity checks | ipify/exit-ip · ipapi/exit-geo · antibrow/fingerprint |
19 commands over 14 sites, including ones that answer a plain scraper with a captcha: Amazon, Walmart, Google, Medium, Yelp, Indeed. See what is published for exactly which ones have returned data here and which need a decent exit IP first.
Missing a platform? Ask for it. The sites with the strictest bot management are the ones this layer is for, and adding one is a pull request in this repo - not a release of the SDK. Open an issue with the site and the data you want, or write it yourself from GUIDE.md; an agent can usually do it in one sitting. Requests for platforms behind Cloudflare, DataDome, PerimeterX or Akamai are welcome: those are the interesting ones, and they are where a per-identity browser with its own exit IP is the difference between getting an answer and getting a challenge page.
One command, N identities
The part that is ours: the same command runs on N isolated identities at once.
anti-detect-browser recipe fanout ipify/exit-ip --profiles 'shopper-*' --concurrency 4
Four profiles, four personas, four cookie jars, four exit IPs, one command. If a site locks one of them, you discard a profile.
What a recipe is
export const meta = {
id: 'reddit/hot',
summary: 'Hot posts from the front page or one subreddit.',
domains: ['www.reddit.com'],
entry: 'https://www.reddit.com/',
identity: 'any',
args: [{ name: 'limit', type: 'number', default: 25, max: 100 }],
}
export async function run(ctx, args) {
const res = await ctx.fetchJson(`/hot.json?limit=${args.limit}`)
return { items: res.data.children.map((c) => ({ id: c.data.id, title: c.data.title })) }
}
No imports, no dependencies, no build step. run() executes inside the page,
so relative fetches carry that profile's session for that site.
Safety
A recipe runs in a browser profile that may hold live logins, so the client treats it the way it would treat a browser extension:
meta.domainsis enforced at the network layer. A request to a host the recipe did not declare is blocked, so a Reddit recipe cannot reach your mail.- Recipes are pinned by SHA-256 and only
reviewedones run by default.--allow-unreviewedopts in, and only on a--temporaryprofile. scripts/check.mjsis a convenience for reviewers, not the boundary. Read the recipe you are about to run; it is one screen of code.
What is published
19 commands over 14 sites. Everything marked reviewed has returned real data
from a throwaway profile on this machine; recipe list marks the rest.
| Reviewed | reddit/hot reddit/search reddit/comments hackernews/top hackernews/item github/repo pypi/package npm/package duckduckgo/search medium/tag amazon/search walmart/search ipify/exit-ip ipapi/exit-geo antibrow/fingerprint |
| Not reviewed yet | google/search indeed/jobs yelp/search x/timeline - see below |
The unreviewed ones need --allow-unreviewed and a --temporary profile. That
is the point of the flag: a recipe nobody has seen work should not run against a
profile you keep.
The unreviewed four need a decent exit IP
They are written and their challenge detection is verified, but none of them returned data here from a cold throwaway profile on a flagged exit:
| recipe | what stopped it | what it needs |
|---|---|---|
google/search | consent wall, intermittently - the same recipe got a clean result page on one run and a wall on the next | a clean residential exit, and a profile that has accepted consent once (so run it on a profile you keep, not --temporary) |
indeed/jobs | Cloudflare interstitial | a clean residential exit |
yelp/search | anti-bot challenge (the vendor's challenge frame is on a host the allowlist blocks, so it can never be solved in-page) | a clean residential exit |
x/timeline | not signed in | a profile signed in to x, ideally on the exit that account is normally used from |
This is not something a recipe can fix. Exit reputation, request cadence and the account history a profile carries decide whether these sites answer at all, and none of the three is a property of the parsing code. Every one of them reports the challenge explicitly rather than returning an empty list, so on a fanout you can see which identity got stopped.
Contributing
Read GUIDE.md - or have your agent read it:
anti-detect-browser recipe guide
Then:
anti-detect-browser recipe scaffold <site>/<command>
node scripts/check.mjs --fix
anti-detect-browser recipe test <site>/<command>
One site per pull request. Explore the site from a throwaway profile, never your own account.
License
MIT. See LICENSE.