phantomwright
v1.59.3
Published
Undetected browser automation SDK with captcha solving and human simulation
Readme
phantomwright
Undetected browser automation SDK — stealth Playwright + Cloudflare solving + human simulation
phantomwright wraps phantomwright-driver (a stealth-patched Playwright fork) and adds:
- 👤 Human simulation — Bézier-curve mouse movement, natural typing delays, idle micro-movements
- 🛡️ Cloudflare solving — automatic Turnstile and Interstitial challenge detection and resolution
- 🎭 Full Playwright/Patchright API — drop-in replacement, works with existing Playwright code
Package changelog: CHANGELOG.md
Installation
npm install phantomwright
npx phantomwright-driver install --with-deps chromiumQuick start
import { chromium } from 'phantomwright';
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();CommonJS also works:
const { chromium } = require('phantomwright');Human simulation
UserSimulator
High-level class that replaces raw Playwright actions with human-like equivalents.
import { chromium, UserSimulator } from 'phantomwright';
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage({ viewport: { width: 1280, height: 900 } });
await page.goto('https://example.com/login');
const sim = await UserSimulator.create(page, { visualizeMouse: true });
// Human-like click via Bézier curve mouse path
await sim.click(page.locator('button#login'));
// Natural typing with randomised delays
await sim.type(page.locator('input[name="email"]'), '[email protected]');
await sim.type(page.locator('input[name="password"]'), 's3cr3t');
await sim.click(page.locator('button[type="submit"]'));
await browser.close();Browsing simulation
const sim = await UserSimulator.create(page);
// Navigate with automatic cool-down behaviour
await sim.navigateToUrl('https://example.com');
// Simulate casual browsing: scrolling + idle movements
await sim.simulateBrowsing(3000); // 3 seconds
// Simulate reading: slower scroll + pauses
await sim.scrollAndRead(2000);Low-level utilities
import { waitHuman, moveToTarget, scrollHuman } from 'phantomwright';
// Human-like pause with triangular distribution
await waitHuman(500, 1000); // 500–1000 ms
// Move mouse via Bézier curve
await moveToTarget(page.mouse, 500, 300, { currentX: 100, currentY: 100 });
// Human-like scrolling in small steps
await scrollHuman(page, 200); // scroll down 200 pxCloudflare challenge solving
Automatically detects and solves Cloudflare Turnstile and Interstitial challenges.
import { chromium, CloudflareSolver } from 'phantomwright';
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const solver = new CloudflareSolver(context, {
maxAttempts: 3,
attemptDelay: 5,
logCallback: (log) => console.log(JSON.parse(log)),
});
// Must call start() before navigation
solver.start();
const page = await context.newPage();
await page.goto('https://protected-site.com');
await browser.close();API reference
Playwright / phantomwright-driver re-exports
All of the Playwright API is available directly:
chromium · firefox · webkit · devices · selectors · request · errors · ...UserSimulator
| Method | Description |
|---|---|
| UserSimulator.create(page, opts?) | Create a new simulator instance |
| sim.click(locator) | Human-like click with Bézier mouse path |
| sim.type(locator, text) | Human-like typing with natural delays |
| sim.navigateToUrl(url) | Navigate with human cool-down |
| sim.simulateBrowsing(ms) | Scrolling + idle movements for N ms |
| sim.scrollAndRead(ms) | Slower scroll simulating reading |
Low-level exports
| Export | Description |
|---|---|
| waitHuman(min, max?) | Human-like pause with triangular distribution |
| moveToTarget(mouse, x, y, opts) | Move mouse via Bézier curve |
| moveToBox(mouse, box, opts) | Move to centre of a bounding box |
| scrollHuman(page, deltaY) | Human-like scroll in small steps |
| bringIntoView(page, box, viewport) | Scroll element into the viewport |
| idleHuman(mouse, page, opts) | Small idle micro-movements |
| VISUAL_CURSOR_JS | Script for in-browser cursor visualisation |
Cloudflare solver exports
| Export | Description |
|---|---|
| CloudflareSolver | Auto-solve Cloudflare Turnstile / Interstitial |
| CloudflareSolverOptions | maxAttempts, attemptDelay, logCallback |
| ChallengeType | Enum: TURNSTILE or INTERSTITIAL |
| detectCloudflareChallenge(page, type) | Detect a specific challenge type |
| detectCfChallengeType(page) | Detect which type is present |
| SolveReport | JSON log structure for solve results |
TypeScript support
Full TypeScript declarations are included. Both ESM and CommonJS are supported:
import { chromium } from 'phantomwright'(ESM)const { chromium } = require('phantomwright')(CJS)
