Headless Chromium fails the one fingerprint check it can't fake: WebGL rendering with no GPU behind it. Our own benchmark found that every Chromium-based stealth engine we tested (native spoofing, JS-patched, CDP-direct) failed that exact check, and the one engine that passed cleanly wasn't Chromium at all. Camoufox is a patched build of Firefox purpose-built for scraping: it doesn't inject spoofing JavaScript into the page (a common detection vector for other stealth tools) but patches the browser's C++ internals directly, and it renders WebGL for real because it's running a real, if firewalled, Firefox engine. This guide installs it, launches it with the config that actually matters, verifies what changed, and is honest about the wall it still hits.
Why a patched Firefox instead of a patched Chromium
Most browser-automation stealth tools start from Chromium (undetected-chromedriver, nodriver, Playwright-Stealth, patchright) because Chromium is what Playwright and Puppeteer drive by default. The problem is that headless Chromium has a structural tell no amount of JavaScript patching fixes cleanly: without a real GPU behind it, WebGL rendering either fails outright or returns a signature that doesn't match what a real machine reports. We measured this directly: three Chromium-based engines (one with native C++ spoofing, one with JS-patched properties, one driving Chrome directly over CDP) all failed the WebGL check on bot.sannysoft.com's test suite. Camoufox was the only one of the four that passed it cleanly, because it isn't Chromium at all.
Camoufox is a fork of Firefox with the spoofing built into the browser's own C++ layer: navigator properties, WebGL vendor/renderer strings, font enumeration, and dozens of other fingerprint surfaces are patched at compile time rather than overwritten by an injected content script after the page loads. That distinction matters because JS-injected patches are themselves inspectable: a site can check whether navigator.webdriver's property descriptor looks native or looks redefined, and a redefined one is a tell independent of what value it returns. Camoufox's approach avoids that class of detection by not injecting anything to detect.
Install it
pip install -U "camoufox[geoip]"
python -m camoufox fetch
The [geoip] extra pulls in an offline dataset that maps an IP to longitude, latitude, timezone, country, and locale. Skip it only if you never plan to pass a proxy. python -m camoufox fetch downloads the actual patched Firefox binary; nothing launches until that step completes. Add [gui] instead (or alongside) if you want the desktop app for managing multiple bundled versions, though the CLI/API path above is what a scraper actually runs in production.
Launch it
The API mirrors Playwright closely enough that porting an existing Playwright scraper is mostly an import swap:
from camoufox.async_api import AsyncCamoufox
async with AsyncCamoufox(headless=True) as browser:
page = await browser.new_page()
await page.goto("https://example.com")
title = await page.title()
print(title)
A sync version exists too (from camoufox.sync_api import Camoufox) with identical arguments, for scripts that don't need asyncio. Both accept the same config kwargs: the ones below are what actually moves detection outcomes, not the full parameter list.
from camoufox.async_api import AsyncCamoufox
async with AsyncCamoufox(
headless="virtual", # Xvfb on Linux — real headful rendering, no visible display
os=("windows", "macos"), # pick one at random per launch instead of one fixed OS
humanize=1.5, # cap cursor-movement time at 1.5s, still feels less scripted than instant jumps
geoip=True, # infer lon/lat/timezone/locale from the proxy's egress IP
proxy={"server": "http://user:pass@proxy-host:3128"},
) as browser:
page = await browser.new_page()
await page.goto("https://tls.browserleaks.com/json")
print(await page.content())
headless="virtual" is the option worth calling out specifically: on Linux it runs the browser headful behind Xvfb, a real virtual display, rather than Firefox's own headless mode, which matters because a genuinely headful render is closer to what a fingerprint check expects than a headless code path pretending to be headful.
Verify what changed
Same discipline as any anti-detect claim: don't trust the marketing copy, check the actual output. Point Camoufox at a fingerprint-echo endpoint and read back what it reports:
import asyncio
from camoufox.async_api import AsyncCamoufox
async def check():
async with AsyncCamoufox(os="windows", geoip=True) as browser:
page = await browser.new_page()
await page.goto("https://browserleaks.com/webgl")
vendor = await page.text_content("#webgl-vendor")
renderer = await page.text_content("#webgl-renderer")
print("WebGL vendor:", vendor)
print("WebGL renderer:", renderer)
asyncio.run(check())
A real Camoufox launch reports a genuine hardware-shaped WebGL vendor/renderer pair, because it's a real rendering engine, not the empty or software-renderer string headless Chromium tends to return without extra spoofing work. Cross-check navigator.platform and the reported font list against whichever os= value you set; a mismatch there is exactly the kind of inconsistency that undermines the whole point of setting os in the first place.
What Camoufox doesn't fix
This is the part that matters most and gets skipped most often. Camoufox defeats fingerprint-layer detection: the checks that inspect what your browser reports about itself. It does not touch two other layers real anti-bot deployments stack on top:
- IP reputation. A flawless Firefox fingerprint from a datacenter IP with no browsing history is still a datacenter IP. Our stealth-browser-engine-compare-2026 benchmark found all four engines we tested (Camoufox included) hard-403'd against a live Cloudflare Bot Management target with no proxy, despite passing every fingerprint check we threw at them. See proxies for web scraping, explained for what actually moves that signal.
- Behavioral analysis.
humanizehelps against naive mouse-jump detection, but sophisticated anti-bot vendors correlate timing, request cadence, and interaction patterns across a whole session. A single humanized cursor movement doesn't defeat that on its own.
Camoufox vs. the rest of the stealth-browser field
- Need WebGL to render for real (canvas-fingerprinting-sensitive targets): Camoufox is the only engine in our bench that passes cleanly. The Chromium-based options fake or fail it.
- Already have a Playwright scraper and just need OS-consistent fingerprint spoofing: Camoufox's API is close enough to Playwright that porting is mostly an import change.
- Target's block is TLS/JA3, not browser fingerprinting: a full browser is the wrong tool. curl_cffi fixes that layer without the overhead of launching one.
- Target's block is IP reputation or behavioral scoring, not fingerprinting: no browser engine on its own fixes this. Pair Camoufox with a real proxy, or route the fetch through a scraping API that manages both.
Camoufox, patchright, and undetected-chromedriver's descendants (nodriver, zendriver) all converged on the same result against a real Cloudflare Bot Management target in our testing: every one of them 403'd without a residential proxy behind it. The engine choice changes which fingerprint checks you pass on the way there. It doesn't change whether the target's IP-reputation layer lets you in.
When fingerprint spoofing isn't enough: bridge to an API
For a target where the block isn't a fingerprint check at all (rotating anti-bot vendors, IP reputation, CAPTCHAs that solve differently every deployment), maintaining a Camoufox fleet with residential proxies becomes its own ongoing job. Crawlora exposes the same data over plain HTTPS instead:
import requests
r = requests.get(
"https://api.crawlora.net/api/v1/amazon/search",
params={"k": "mechanical keyboard"},
headers={"x-api-key": "YOUR_API_KEY"},
)
data = r.json()
for item in data["data"]:
print(item["asin"], item["list_price"], item["link"])
Fingerprint upkeep, proxy rotation, and CAPTCHA solving happen behind the endpoint, and the response is normalized JSON instead of DOM you have to keep re-selecting after every site redesign. There's an official Python SDK if you'd rather not build the request by hand, and billing is pay-on-success: a blocked or failed fetch costs nothing (pricing). Web scraping vs API walks through when DIY is still the right call.
Wrap-up
Camoufox is a real fix for one specific, well-defined problem: browser-fingerprint checks that trip up headless Chromium, especially WebGL. pip install "camoufox[geoip]", python -m camoufox fetch, AsyncCamoufox(...): that's the whole surface for the common case. Just don't mistake a clean fingerprint check for a bypassed anti-bot system; IP reputation and behavioral scoring are separate layers that a browser engine alone was never going to solve. Try the underlying endpoints in the playground with no code at all, or browse the docs for the full catalog.
Skip the fingerprint-and-proxy stack on hard targets
Structured endpoints, managed proxies and rendering, pay-on-success billing. 2,000 free credits/month, no card.
Related reading
- undetected-chromedriver, nodriver, Playwright-Stealth, Camoufox: 4 engines, one real test: the WebGL/fingerprint data this post's opening claim comes from
- Stealth browser fleet benchmark: 15 engines, including Camoufox, measured at scale
- Web scraping with curl_cffi and curl-impersonate: the TLS-fingerprint layer a browser engine doesn't touch
- Web scraping with Crawlee: pairing Camoufox with a crawling framework's queue, retries, and adaptive HTTP/browser switching
- How websites prevent web scraping in 2026: the full detection-layer landscape Camoufox sits inside
- Proxies for web scraping, explained: the IP-reputation layer fingerprint spoofing doesn't touch
Frequently asked questions
What is Camoufox used for?
Camoufox is a patched build of Firefox purpose-built for web scraping and browser automation. It spoofs navigator properties, WebGL vendor/renderer strings, fonts, and other fingerprint surfaces at the browser's C++ level instead of injecting JavaScript patches after the page loads, which avoids a detection vector other stealth tools are vulnerable to. It's used against sites that fingerprint the browser itself, not just the TLS handshake or the IP address.
Is Camoufox better than undetected-chromedriver or Playwright-Stealth?
For WebGL rendering specifically, yes — our own benchmark found Camoufox was the only engine among four tested (alongside a native-spoofing Chromium engine, a JS-patched Chromium engine, and a CDP-direct Chrome engine) that passed a WebGL fingerprint check cleanly, because it's the only one not running headless Chromium. On every other axis we measured, including a real Cloudflare Bot Management target, all four engines tied.
Does Camoufox bypass Cloudflare or other anti-bot systems?
It bypasses fingerprint-layer checks — the ones that inspect what your browser reports about itself. It does not bypass IP-reputation or behavioral-analysis layers, which real anti-bot deployments stack independently. In our own testing, Camoufox hard-403'd against a live Cloudflare Bot Management target with no proxy behind it, despite passing every fingerprint check we ran.
How do I install Camoufox?
pip install -U "camoufox[geoip]" installs the Python package with the optional geolocation dataset; python -m camoufox fetch then downloads the actual patched Firefox binary — nothing launches until that second step completes. An optional [gui] extra adds a desktop app for managing multiple bundled browser versions.
What does the os= parameter actually change in Camoufox?
Setting os doesn't just rewrite the User-Agent string. Camoufox adjusts navigator.platform, the font list Firefox reports as installed, and other OS-coupled fingerprint surfaces together, so the whole profile stays internally consistent instead of claiming one OS in the User-Agent while leaking a different OS's fonts or platform string.
Camoufox vs curl_cffi — which should I use?
Use curl_cffi when a target's block is a TLS/JA3 handshake check and the content is present in the HTML the server returns — it's far lighter than launching a browser. Use Camoufox when the target actually requires JavaScript execution to render content, or when the fingerprint check specifically inspects browser-level signals like WebGL that curl_cffi, having no browser at all, can't produce.
Is web scraping with Camoufox legal?
Browser fingerprint spoofing is a technical evasion technique, not itself a legal category — legality depends on what data you collect and how. Public data gathered respectfully (rate limits, no login-walled or personal data, checking a site's terms) is generally lower-risk than scraping private or paywalled content behind an authentication wall. Camoufox doesn't change that calculus; it only removes one specific detection obstacle.
