Bumps the javascript group with 6 updates in the /js directory: | Package | From | To | | --- | --- | --- | | [tar](https://github.com/isaacs/node-tar) | `7.5.15` | `7.5.16` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.1` | `26.0.0` | | [playwright-core](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.0` | | [puppeteer-core](https://github.com/puppeteer/puppeteer) | `25.0.4` | `25.2.0` | | [socks-proxy-agent](https://github.com/TooTallNate/proxy-agents/tree/HEAD/packages/socks-proxy-agent) | `10.0.0` | `10.1.0` | | [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `1.6.1` | `3.2.6` | Updates `tar` from 7.5.15 to 7.5.16 - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v7.5.15...v7.5.16) Updates `@types/node` from 25.9.1 to 26.0.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `playwright-core` from 1.60.0 to 1.61.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.60.0...v1.61.0) Updates `puppeteer-core` from 25.0.4 to 25.2.0 - [Release notes](https://github.com/puppeteer/puppeteer/releases) - [Changelog](https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md) - [Commits](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v25.0.4...puppeteer-core-v25.2.0) Updates `socks-proxy-agent` from 10.0.0 to 10.1.0 - [Release notes](https://github.com/TooTallNate/proxy-agents/releases) - [Changelog](https://github.com/TooTallNate/proxy-agents/blob/main/packages/socks-proxy-agent/CHANGELOG.md) - [Commits](https://github.com/TooTallNate/proxy-agents/commits/socks-proxy-agent@10.1.0/packages/socks-proxy-agent) Updates `vitest` from 1.6.1 to 3.2.6 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v3.2.6/packages/vitest) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.0.0 dependency-type: direct:development update-type: version-update:semver-major dependency-group: javascript - dependency-name: playwright-core dependency-version: 1.61.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: javascript - dependency-name: puppeteer-core dependency-version: 25.1.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: javascript - dependency-name: socks-proxy-agent dependency-version: 10.1.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: javascript - dependency-name: tar dependency-version: 7.5.16 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: javascript - dependency-name: vitest dependency-version: 3.2.6 dependency-type: direct:development update-type: version-update:semver-major dependency-group: javascript ... Signed-off-by: dependabot[bot] <support@github.com>
CloakBrowser
Stealth Chromium that passes every bot detection test.
Drop-in Playwright/Puppeteer replacement. Same API, same code — just swap the import. 3 lines of code, 30 seconds to unblock.
- 58 source-level C++ patches — canvas, WebGL, audio, fonts, GPU, screen, WebRTC, network timing, automation signals
- 0.9 reCAPTCHA v3 score — human-level, server-verified
- Passes Cloudflare Turnstile, FingerprintJS, BrowserScan — tested against 30+ detection sites
npm install cloakbrowser— binary auto-downloads, auto-updates, zero config- Free and open source — no subscriptions, no usage limits
- Works with any framework — tested with browser-use, Crawl4AI, Scrapling, Stagehand (example), LangChain, Selenium, and more
Install
# With Playwright
npm install cloakbrowser playwright-core
# With Puppeteer
npm install cloakbrowser puppeteer-core
On first launch, the stealth Chromium binary auto-downloads (~200MB, cached at ~/.cloakbrowser/).
Usage
Playwright (default)
import { launch } from 'cloakbrowser';
const browser = await launch();
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
For sites with anti-bot protection, add a residential proxy and these flags:
const browser = await launch({
proxy: 'http://user:pass@residential-proxy:port',
geoip: true, // match timezone + locale to proxy IP
headless: false, // some sites detect headless even with C++ patches
humanize: true, // human-like mouse, keyboard, scroll
});
See the main README for site-specific troubleshooting (FingerprintJS, Kasada, reCAPTCHA).
Puppeteer
Note: Playwright is recommended for sites with reCAPTCHA Enterprise. Puppeteer's CDP protocol leaks automation signals that reCAPTCHA Enterprise can detect. This is a known Puppeteer limitation, not specific to CloakBrowser.
import { launch } from 'cloakbrowser/puppeteer';
const browser = await launch();
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
Options
import { launch, launchContext, launchPersistentContext } from 'cloakbrowser';
// With proxy (HTTP or SOCKS5)
const browser = await launch({
proxy: 'http://user:pass@proxy:8080',
});
const browser = await launch({
proxy: 'socks5://user:pass@proxy:1080',
});
// With proxy object (bypass, separate auth fields)
const browser = await launch({
proxy: { server: 'http://proxy:8080', bypass: '.google.com', username: 'user', password: 'pass' },
});
// Headed mode (visible browser window)
const browser = await launch({ headless: false });
// Extra Chrome args
const browser = await launch({
args: ['--fingerprint=12345'],
});
// With timezone and locale
const browser = await launch({
timezone: 'America/New_York',
locale: 'en-US',
});
// Auto-detect timezone/locale from proxy IP (requires: npm install mmdb-lib)
const browser = await launch({
proxy: 'http://proxy:8080',
geoip: true,
});
// Browser + context in one call (timezone/locale set via binary flags)
const context = await launchContext({
userAgent: 'Custom UA',
viewport: { width: 1920, height: 1080 },
locale: 'en-US',
timezone: 'America/New_York',
});
// Persistent profile — stay logged in, bypass incognito detection, load extensions
const ctx = await launchPersistentContext({
userDataDir: './chrome-profile',
headless: false,
proxy: 'http://user:pass@proxy:8080',
});
const page = ctx.pages()[0] || await ctx.newPage();
await page.goto('https://example.com');
await ctx.close(); // profile saved — reuse same path to restore state
Auto Timezone/Locale from Proxy IP
When using a proxy, antibot systems check that your browser's timezone and locale match the proxy's location. Install mmdb-lib to enable auto-detection from an offline GeoIP database (~70 MB, downloaded on first use):
npm install mmdb-lib
// Auto-detect — timezone and locale set from proxy's IP geolocation
const browser = await launch({ proxy: 'http://proxy:8080', geoip: true });
// Works with launchContext too
const context = await launchContext({ proxy: 'http://proxy:8080', geoip: true });
// Explicit values always win over auto-detection
const browser = await launch({ proxy: 'http://proxy:8080', geoip: true, timezone: 'Europe/London' });
Note: For rotating residential proxies, the DNS-resolved IP may differ from the exit IP. Pass explicit
timezone/localein those cases.
CLI
Pre-download the binary or check installation status from the command line:
npx cloakbrowser install # Download binary with progress output
npx cloakbrowser info # Show version, path, platform
npx cloakbrowser update # Check for and download newer binary
npx cloakbrowser clear-cache # Remove cached binaries
Utilities
import { ensureBinary, clearCache, binaryInfo, checkForUpdate } from 'cloakbrowser';
// Pre-download binary (e.g., during Docker build)
await ensureBinary();
// Check installation
console.log(binaryInfo());
// Force re-download
clearCache();
// Manually check for newer Chromium version
const newVersion = await checkForUpdate();
if (newVersion) console.log(`Updated to ${newVersion}`);
Test Results
| Detection Service | Stock Browser | CloakBrowser |
|---|---|---|
| reCAPTCHA v3 | 0.1 (bot) | 0.9 (human) |
| Cloudflare Turnstile | FAIL | PASS |
| FingerprintJS | DETECTED | PASS |
| BrowserScan | DETECTED | NORMAL (4/4) |
| bot.incolumitas.com | 13 fails | 1 fail |
navigator.webdriver |
true |
false |
| CDP detection | Detected | Not detected |
| TLS fingerprint | Mismatch | Identical to Chrome |
| Tested against 30+ detection sites |
Configuration
| Env Variable | Default | Description |
|---|---|---|
CLOAKBROWSER_BINARY_PATH |
— | Skip download, use a local Chromium binary |
CLOAKBROWSER_CACHE_DIR |
~/.cloakbrowser |
Binary cache directory |
CLOAKBROWSER_DOWNLOAD_URL |
cloakbrowser.dev |
Custom download URL |
CLOAKBROWSER_AUTO_UPDATE |
true |
Set to false to disable background update checks |
CLOAKBROWSER_SKIP_CHECKSUM |
false |
Set to true to skip SHA-256 verification after download |
CLOAKBROWSER_WIDEVINE_CDM |
— | Path to a sideloaded WidevineCdm directory (overrides auto-detection next to the binary) |
CLOAKBROWSER_WIDEVINE |
1 |
Set to 0 to disable automatic Widevine hint-file seeding for persistent contexts |
Widevine / DRM
The binary supports Widevine, but the CDM is proprietary and can't be redistributed. Sideload it once by copying a WidevineCdm/ directory from a real Chrome install next to the binary (full steps in #96):
cp -r /opt/google/chrome/WidevineCdm ~/.cloakbrowser/chromium-<version>/WidevineCdm
With the CDM in place, launchPersistentContext() enables Widevine on the first launch — the wrapper auto-seeds the CDM hint file into the profile. This plays DRM-protected video (Netflix, Spotify Web) and makes a persistent profile present as a regular Chrome install to detection services that probe for DRM/EME support. Linux only. A sideloaded CDM is the opt-in (no flag); set CLOAKBROWSER_WIDEVINE_CDM for a custom path or CLOAKBROWSER_WIDEVINE=0 to disable. See the main README for details.
Migrate From Playwright
- import { chromium } from 'playwright';
- const browser = await chromium.launch();
+ import { launch } from 'cloakbrowser';
+ const browser = await launch();
const page = await browser.newPage();
// ... rest of your code works unchanged
Platforms
| Platform | Chromium | Patches | Status |
|---|---|---|---|
| Linux x86_64 | 146 | 58 | ✅ Latest |
| Linux arm64 (RPi, Graviton) | 146 | 58 | ✅ |
| macOS arm64 (Apple Silicon) | 145 | 26 | ✅ |
| macOS x86_64 (Intel) | 145 | 26 | ✅ |
| Windows x86_64 | 146 | 58 | ✅ Latest |
CloakBrowser Pro
The wrapper (Python + JS) is MIT, free forever. The binary uses a delayed free-release model:
- Free (v146) — free forever on GitHub Releases. Unlimited sessions. Works today, goes stale as detection evolves.
- Pro (latest, v148) — the newest patches and Chromium upgrades first, so the test results stay green as anti-bot systems change. Linux + Windows (macOS coming).
Anti-bot detection updates constantly — an older binary degrades within weeks. Pro keeps you on the build that's actively maintained against it.
Activate with your license key (env var, licenseKey option, or ~/.cloakbrowser/license.key):
export CLOAKBROWSER_LICENSE_KEY=cb_xxxxxxxx
Pro plans → cloakbrowser.dev
Requirements
- Node.js >= 20
- One of:
playwright-core>= 1.53 orpuppeteer-core>= 21
Troubleshooting
Site detects incognito / private browsing mode
By default, launch() opens an incognito context. Some sites (like BrowserScan) detect this. Use launchPersistentContext() instead — it runs with a real user profile:
import { launchPersistentContext } from 'cloakbrowser';
const ctx = await launchPersistentContext({
userDataDir: './my-profile',
headless: false,
});
// Load Chrome extensions
const ctx = await launchPersistentContext({
userDataDir: './my-profile',
headless: false,
extensionPaths: ['./my-extension'],
});
This also gives you cookie and localStorage persistence across sessions.
reCAPTCHA v3 scores are low (0.1–0.3)
Avoid page.waitForTimeout() — it sends CDP protocol commands that reCAPTCHA detects. Use native sleep instead:
// Bad — sends CDP commands, reCAPTCHA detects this
await page.waitForTimeout(3000);
// Good — invisible to the browser
await new Promise(r => setTimeout(r, 3000));
Other tips for maximizing reCAPTCHA scores:
- Use Playwright, not Puppeteer — Puppeteer sends more CDP protocol traffic that reCAPTCHA detects (details)
- Use residential proxies — datacenter IPs are flagged by IP reputation, not browser fingerprint
- Spend 15+ seconds on the page before triggering reCAPTCHA — short visits score lower
- Space out requests — back-to-back
grecaptcha.execute()calls from the same session get penalized. Wait 30+ seconds between pages with reCAPTCHA - Use a fixed fingerprint seed (
--fingerprint=12345) for consistent device identity across sessions - Use
page.type()instead ofpage.fill()for form filling —fill()sets values directly without keyboard events, which reCAPTCHA's behavioral analysis flags.type()with a delay simulates real keystrokes:await page.type('#email', 'user@example.com', { delay: 50 }); - Minimize
page.evaluate()calls before the reCAPTCHA check fires — each one sends CDP traffic
New update broke something? Roll back to the previous version
When auto-update downloads a newer binary, the previous version stays in ~/.cloakbrowser/. Point CLOAKBROWSER_BINARY_PATH to the older cached binary:
# Linux
export CLOAKBROWSER_BINARY_PATH=~/.cloakbrowser/chromium-146.0.7680.177.4/chrome
# macOS
export CLOAKBROWSER_BINARY_PATH=~/.cloakbrowser/chromium-145.0.7632.109.2/Chromium.app/Contents/MacOS/Chromium
# Windows
set CLOAKBROWSER_BINARY_PATH=%USERPROFILE%\.cloakbrowser\chromium-146.0.7680.177.4\chrome.exe
Links
- 🌐 Website
- 🐛 Bug reports & feature requests
- 📦 PyPI (Python package)
- 📖 Full documentation
- 📧 Contact: cloakhq@pm.me
License
- Wrapper code (this repository) — MIT. See LICENSE.
- CloakBrowser binary (compiled Chromium) — free to use, no redistribution. See BINARY-LICENSE.md.
Use against financial, banking, healthcare, or government authentication systems without authorization is expressly prohibited.
