invisible_playwright: A source-patched Firefox for undetected Playwright automation
Undetected Playwright automation in Python. Stealth-patched Firefox, anti-detect browser fingerprint in the engine, not injected. Passes bot detection.
At a glance
- What is it?
- invisible_playwright replaces Playwright's stock Firefox with a C++-patched engine that sets a full browser fingerprint at the source level, not via injected JavaScript. It aims to pass reCAPTCHA, hCaptcha, and Cloudflare Turnstile while keeping the standard Playwright API intact.
- Who is it for?
- Adopt invisible_playwright if you run Playwright-based scraping or automation in Python on Windows x86_64, Linux x86_64, or Linux arm64, and you need a fingerprint that is set inside the engine rather than injected. Do not adopt it if you are on macOS, which is unsupported and will refuse to launch, or if you need a Chromium-based stack.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What this library actually changes
invisible_playwright is not a wrapper that hides Playwright's automation flags. It is a distribution of Firefox that has been patched at the C++ source level. The README states that the fingerprint is set inside the engine, not injected into the page. That means navigator, screen, GPU/WebGL, canvas, fonts, audio, WebRTC, timezone, and network values are all produced by the engine itself. There is no JS shim and no override, so a site inspecting the page for injected properties finds nothing. The project claims that headless and headed modes produce the same values, which is a meaningful difference from typical stealth approaches where headless mode leaks differences. The patched engine is distributed as a separate repository, feder-cr/firefox_antidetect_patch, and invisible_playwright is the Python driver that manages it.
The two-question model behind the stealth
The project frames anti-bot detection as two questions. First, is this a real browser? The patched Firefox answers yes because the fingerprint is native. Second, is a real person using it? The driver humanizes input actions. Every click, hover, and drag follows a natural mouse path with human timing, and each input is byte-identical to a real mouse, including the input source, pressure, and trusted events. This is not a set of random delays bolted onto Playwright. The mouse movement uses Bezier curves, and the README gives an example where page.click('#submit') makes the mouse arc to the button. The library also generates a distinct fingerprint per session, covering roughly 200 fields including GPU, audio, fonts, and screen. This addresses the common failure where a static fingerprint is reused across sessions and becomes detectable.
Installation and the two-line switch
Installation is a pip package plus a one-time engine download. The README gives these exact commands: pip install invisible-playwright, then python -m invisible_playwright fetch. That fetch downloads about 238 MB, unpacks to roughly 544 MB, and verifies with sha256. The supported platforms are Windows x86_64, Linux x86_64, and Linux arm64. macOS support has been dropped, and the package refuses to launch on a Mac with a clear message instead of downloading a binary that no longer exists. The API is identical to Playwright's. The README shows a diff where you replace from playwright.sync_api import sync_playwright and the launch call with from invisible_playwright import InvisiblePlaywright and a context manager. The browser object you get back is a standard playwright.sync_api.Browser, so every Playwright method works without changes. Both sync and async variants are provided.
Fingerprint seeds and pinning specific fields
Each session gets a random fingerprint, but you can control it. The InvisiblePlaywright constructor accepts a seed parameter. With seed=42, the README says you get the same GPU, canvas hash, and audio context on every run. This is useful for reproducing a session or debugging a detection issue. There is also a pin parameter that forces specific values while the rest remain seed-derived. The example pins gpu.renderer, gpu.vendor, screen.width, screen.height, and hardware.concurrency. The full list of pinnable keys and how pinning interacts with the Bayesian sampler is documented in docs/pinning.md. The mention of a Bayesian sampler is notable. It suggests the fingerprint generation is not a random pick from a list but a sampled distribution, which is a more sophisticated approach than most stealth libraries. That said, the README does not explain the sampler in detail, so you would need to read the linked document to understand the exact behavior.
Proxies, timezone, and the IP reality check
The library accepts a proxy dict with server, username, and password. Supported schemes are socks5, socks4, http, and https. DNS is routed through the proxy by default, which the README says prevents local leaks. The timezone is auto-derived from the egress IP, either the proxy's or the host's public IP. You can force a specific IANA zone with timezone='America/New_York', and that explicit value always wins. The project is blunt about a key limitation: once the browser is handled, the proxy becomes the variable. The README states that around 90% of proxies are public, meaning anyone can rent the same address, so it is already known and sits on blocked-IP lists. A perfect browser on a known IP still loses. This is a practical warning, not a marketing claim. It tells you that this library solves the browser side, not the IP side.
The CLI and the documented ecosystem
The installed command is invisible-playwright with a hyphen, and python -m invisible_playwright works identically. The CLI has two subcommands: fetch, which downloads the engine if missing, checks every cached one against the seal, and prints the path; and version, which prints wrapper, core, and engine versions plus the cache location. The project maintains an extensive wiki with four sections: documentation, guides, comparisons, and integrations. The guides explain detection in seven groups, including browser identity, canvas/WebGL/fonts/audio, network and WebRTC, the automation layer, AI agents, and the detectors themselves explained from source. The comparisons page covers Camoufox, Patchright, nodriver, and playwright-stealth, and argues for Firefox over Chromium. The integrations page lists Scrapy, Crawlee, Robot Framework, CodeceptJS, test runners, Playwright MCP, and names the frameworks it does not fit. This is a project that expects you to read before adopting.
Limitations and the wrong-tool cases
The most obvious limitation is platform support. macOS is out. If you develop on a Mac and deploy to Linux, you can still use it, but you cannot run it locally on the Mac. The engine download is large, and the unpacked size of 544 MB is not trivial for containerized or ephemeral environments. The README does not mention how the engine is cached or whether it can be pre-seeded in a CI image, so you may need to handle that yourself. There is also the proxy dependency: the project itself says the browser is not the variable once it is handled, so if you see captchas, the proxy is the likely cause. That means this library is not a magic bullet. It is also not a fit for frameworks that require a Chromium-specific API or that assume a stock Playwright browser. The wiki names the frameworks it does not fit, but the README truncates before listing them, so you must check that page. Finally, the project makes strong claims about passing every bot detection test, but the README does not name the tests or show methodology. Treat that as a marketing statement until you verify on your target sites.
Alternatives and the Firefox-over-Chromium argument
The project's own comparisons page lists Camoufox, Patchright, nodriver, and playwright-stealth. The key difference in approach is that invisible_playwright patches Firefox at the C++ level, while playwright-stealth and Patchright typically work by injecting JavaScript overrides into Chromium or patching the Playwright driver. Nodriver is a different automation library that drives the browser without the WebDriver protocol, which is a fundamentally different mechanism. Camoufox, according to the project's comparison, is also a patched Firefox but the README does not detail how it differs in implementation. The project argues for Firefox over Chromium, which is a claim you should evaluate against your target sites, since some sites are more familiar with Chromium fingerprints. The practical difference is that injected overrides can be detected by reading the page for non-native properties, while a source-level patch has no such seam. But a source-level patch means you are tied to the project's Firefox version and its release cadence, which is a maintenance cost you do not have with a pure JS shim.
Editorial conclusion
Adopt invisible_playwright if you run Playwright-based scraping or automation in Python on Windows x86_64, Linux x86_64, or Linux arm64, and you need a fingerprint that is set inside the engine rather than injected. Do not adopt it if you are on macOS, which is unsupported and will refuse to launch, or if you need a Chromium-based stack. Before committing, verify that the proxy you intend to use is not a public or shared IP, because the project states that roughly 90% of proxies are public and a known IP will still trigger challenges regardless of the browser. Also verify that the 238 MB download and ~544 MB unpacked footprint are acceptable for your deployment environment, and check the wiki's integrations page for the frameworks it does not fit before wiring it into a larger system.
Community notes