Anti-Detect Browser that passes every bot detection test. Drop-in Playwright replacement. https://github.com/feder-cr/invisible_playwright#why-its-powerful
Find a file
2026-06-25 04:31:47 +02:00
.githooks ci: add pre-push hook to block red pushes 2026-05-20 13:25:08 -07:00
.github chore: remove LLM-style phrasing from issue templates 2026-06-25 04:16:47 +02:00
docs docs(hero.gif): remove top dark band, top-align screenshots 2026-05-25 22:51:51 -07:00
examples feat: initial public release 2026-05-12 22:32:58 -07:00
scripts Drive gate: set the realistic newtab prefs so a human-cursor click can't lose the about:newtab race 2026-06-16 23:40:29 +02:00
src/invisible_playwright fix(fonts): core pool uses the real Win11 family "franklin gothic medium" 2026-06-24 09:37:11 +02:00
tests Geo-aware locale, audio noise off, font prefs for the bundled-font binary 2026-06-23 17:51:58 +02:00
.gitignore feat: initial public release 2026-05-12 22:32:58 -07:00
CHANGELOG.md Pin firefox-12: cross-OS render parity + always-present standard fonts 2026-06-19 03:19:30 +02:00
CODE_OF_CONDUCT.md chore: add community standards (CoC, contributing, security, templates) 2026-05-18 11:46:16 -07:00
CONTRIBUTING.md docs: rename source-fork repo references invisible-firefox -> invisible_firefox 2026-05-23 11:09:27 -07:00
LICENSE feat: initial public release 2026-05-12 22:32:58 -07:00
pyproject.toml test: activate the full e2e (browser-driving) suite + add fetch --force 2026-06-09 15:40:02 +02:00
README.md docs: remove LLM phrasing throughout README 2026-06-25 04:31:47 +02:00
SECURITY.md docs: rewrite SECURITY.md, add disclaimer, remove LLM language 2026-06-25 04:22:39 +02:00

invisible_playwright

tests License: MIT Python 3.11+ Firefox 150.0.1 GitHub release GitHub stars browser launches

LinkedIn

Stealth Firefox that passes every bot detection test. Drop-in Playwright replacement, fingerprint patched at the C++ level, not a JavaScript shim.

invisible_playwright - 5/5 detection suites passed

How it works

Most other anti-detect browsers patch Chromium at the JavaScript level - they override navigator, WebGLRenderingContext.getParameter, canvas APIs, and so on via injected scripts. This has two fatal problems:

  1. JS patches are detectable. Anti-bots enumerate native function .toString(), check descriptor configurability, compare property enumeration order, watch for prototype mutations. Every patch leaves a fingerprint of its own. CreepJS has an entire battery of "lies detectors" built around this.
  2. Chromium itself is now suspect. Forks cant fully match Chrome: it ships closed-source components (Widevine, proprietary codecs, Safe Browsing) that flip detectable JS flags and network signals, and forks lag Chromes release cadence, leaving version-specific tells detectors lock onto.

invisible_playwright patches Firefox at the C++ level — no JS shim, no Object.defineProperty. Spoofed values come out through normal Gecko paths: Navigator, screen, GPU/WebGL, Canvas, fonts, audio, WebRTC, timezone, DevTools, SOCKS5. See feder-cr/invisible_firefox for the full breakdown.


How it compares

CloakBrowser is closed source (patches not published) and hits the Chromium reCAPTCHA ceiling. Multilogin, GoLogin, AdsPower, Dolphin, Kameleo are paid SaaS running JS-layer spoofing on a patched Chromium.

invisible_playwright Camoufox CloakBrowser Multilogin
Engine Firefox 150 Firefox (~1 year old base) Chromium Chromium fork
Patch depth C++ source C++ source C++ source JS overrides
Maintenance Active Gap (~1 year) Active Active SaaS
Open source MIT MPL Closed source Closed source
.toString() clean Detectable shims
Canvas / WebGL / Audio C++ ⚠️ Drift vs current FF C++ ⚠️ JS override
SOCKS5 auth Patched ⚠️ Playwright proxy ⚠️ Varies
reCAPTCHA v3 score 0.90 ~0.3-0.5 ~0.3-0.5 ~0.3-0.6
FP Pro - bot detected Not detected Detected Detected Detected
CreepJS lies 0 Multiple 0 Multiple
Cost Free Free Free From $99/mo

Install

pip install git+https://github.com/feder-cr/invisible_playwright.git
python -m invisible_playwright fetch      # one-time ~100 MB download, SHA256-verified

Supported platforms: Windows x86_64, Linux x86_64 / arm64, macOS arm64 / x86_64. On macOS the app is ad-hoc signed (not notarized): if Gatekeeper complains, clear the quarantine flag once with xattr -dr com.apple.quarantine on the cached Firefox.app.


Usage

Random fingerprint per session

100% Playwright-compatible - sync and async, all methods, zero API changes. If you already use Playwright, switching is two lines:

- from playwright.sync_api import sync_playwright
- with sync_playwright() as p:
-     browser = p.firefox.launch()
+ from invisible_playwright import InvisiblePlaywright
+ with InvisiblePlaywright() as browser:

Every session gets a distinct fingerprint (GPU, audio, fonts, screen, ~400 fields) and Bezier-curve mouse motion.

Sync

from invisible_playwright import InvisiblePlaywright

with InvisiblePlaywright(proxy={"server": "socks5://...", "username": "u", "password": "p"}) as browser:
    page = browser.new_page()
    page.goto("https://example.com")
    page.click("#submit")   # mouse arcs to the button on a Bezier curve

Async

from invisible_playwright.async_api import InvisiblePlaywright

async with InvisiblePlaywright(proxy={"server": "socks5://...", "username": "u", "password": "p"}) as browser:
    page = await browser.new_page()
    await page.goto("https://example.com")
    await page.click("#submit")

The browser object is a playwright.sync_api.Browser / playwright.async_api.Browser - every Playwright method works as-is.

Log the seed to replay a run:

sf = InvisiblePlaywright()
with sf as browser:
    print("seed =", sf.seed)
    # ...

Reproducible fingerprint

with InvisiblePlaywright(seed=42) as browser:
    ...   # same GPU, same canvas hash, same audio context, every run

Proxies

proxy = {
    "server": "socks5://gate.example.com:1080",
    "username": "user",
    "password": "pass",
}
with InvisiblePlaywright(proxy=proxy) as browser:
    ...

Schemes supported: socks5, socks4, http, https. DNS is routed through the proxy by default, no local leak.

Timezone

The browser timezone follows timezone=:

# default: timezone is auto-derived from the egress IP (proxy egress if a
# proxy is set, otherwise the host's own public IP)
with InvisiblePlaywright(proxy=proxy) as browser:
    ...

# explicit IANA zone always wins — the only way to force a specific zone
with InvisiblePlaywright(proxy=proxy, timezone="America/New_York") as browser:
    ...

Pinning specific fingerprint fields

By default everything comes from seed. To force specific values while the rest stays seed-derived:

with InvisiblePlaywright(
    seed=42,
    pin={
        "gpu.renderer": "ANGLE (NVIDIA, NVIDIA GeForce RTX 4090 Direct3D11)",
        "gpu.vendor":   "Google Inc. (NVIDIA)",
        "screen.width":  2560,
        "screen.height": 1440,
        "hardware.concurrency": 16,
    },
) as browser:
    ...

Full list of pinnable keys, how pinning interacts with the Bayesian sampler, and common patterns are in docs/pinning.md.


CLI

invisible_playwright fetch          # download the binary if missing
invisible_playwright fetch --force  # re-download even if cached
invisible_playwright path           # print the absolute path to the cached binary
invisible_playwright version        # wrapper and binary versions
invisible_playwright clear-cache    # remove all cached binaries

Related projects that cover similar ground:

  • arkenfox/user.js - Firefox privacy hardening via prefs. invisible_playwright patches C++ where prefs are insufficient.
  • LibreWolf - Firefox fork with privacy defaults. LibreWolf ships a configured binary; invisible_playwright ships source patches + automation wrapper.
  • Camoufox - open-source anti-detect Firefox. Patches a wider surface and ships its own fingerprint database; invisible_playwright uses a Bayesian sampler.

License

MIT - see LICENSE. The patched Firefox binary is distributed under the MPL-2.0 (Firefox upstream license). The C++ patches against mozilla-central that produce that binary are at feder-cr/invisible_firefox.


Disclaimer

This project is for educational purposes only. It is provided as-is, with no warranties. I take no responsibility for how it is used. Use it at your own risk and in compliance with the laws of your jurisdiction.