Build with Mimic.
Start the local browser runtime, connect a standard automation client over CDP, and configure the observable environment your workflow needs.
Mimic.* commands provide runtime-specific configuration and control.Getting started
Download the latest Windows or Linux archive from GitHub Releases, verify it against the included SHA256SUMS, and extract it. No Chrome, Go, Rust, display server, or GPU is required for the packaged executable.
| Platform | Runtime requirements |
|---|---|
| Windows amd64 | Verified on Windows 11. Run mimic.exe. |
| Linux amd64 | glibc 2.39+, libgcc_s, and installed Liberation, DejaVu, or Noto fonts. Ubuntu 24.04+. |
# Windows
.\mimic.exe --listen 127.0.0.1:9222
# Linux
./mimic --listen 127.0.0.1:9222Keep the process running while your client is connected. The endpoint has no authentication and is intended for trusted local clients.
Playwright
Install playwright-core so the client does not download a browser:
npm install playwright-core
import { chromium } from "playwright-core";
const browser = await chromium.connectOverCDP("http://127.0.0.1:9222");
try {
const context = browser.contexts()[0];
const page = await context.newPage();
await page.goto("https://example.com/", { waitUntil: "load" });
console.log(await page.locator("h1").textContent());
} finally {
// This disconnects the client; it does not own the Mimic process.
await browser.close();
}Wait for an application-specific element or state when hydration continues after the load event. Supported workflows include locators, forms, fetch-driven DOM updates, frames, Shadow DOM, popups, cookies, history, multiple Pages, and network events; this is not a promise that every Playwright feature is available.
Puppeteer
npm install puppeteer-core@25.10.0
import puppeteer from "puppeteer-core";
const browser = await puppeteer.connect({
browserURL: "http://127.0.0.1:9222",
defaultViewport: null
});
const page = await browser.newPage();
await page.goto("https://example.com/", { waitUntil: "load" });
console.log(await page.$eval("h1", node => node.textContent));
await page.close();
await browser.disconnect();CLI reference
| Flag | Default | Purpose |
|---|---|---|
--listen | 127.0.0.1:9222 | CDP HTTP and WebSocket address. |
--chrome | 152 | Loaded Chrome compatibility milestone. It does not install Chrome. |
--profile | none | JSON environment profile for new contexts. |
--browser-mode | headful | Chooses the environment profile; it does not open a window. |
--engine | v8 | JavaScript engine: v8, quickjs, or goja. Fallbacks do not promise V8 equivalence. |
--navigation-timeout | 0 | Optional navigation execution cap. Zero waits until completion or cancellation. |
--dev-preview | false | Enables the visual debug viewer at /debug/preview/; this is not native rendering. |
Environment profiles
Schema version 1 configures a BrowserContext before its first page loads. Pages, frames, and new workers inherit the Context environment. Full replacement requires a new Context; existing cookies, documents, and JavaScript are not migrated.
{
"schemaVersion": 1,
"baseProfile": "chrome-152-windows-x64-headful-controlled-v1",
"display": { "width": 1920, "height": 1080, "deviceScaleFactor": 1 },
"window": { "viewportWidth": 1280, "viewportHeight": 720 },
"hardware": { "logicalProcessors": 8, "deviceMemoryGB": 8 },
"locale": {
"languages": ["en-US", "en"],
"timezone": "America/New_York",
"intlLocale": "en-US"
},
"preferences": { "colorScheme": "dark", "reducedMotion": false }
}Unknown fields, nulls, wrong types, and unsupported custom values return explicit validation errors. Objects merge named members into the base; arrays replace their complete value. Query Mimic.getProfileSchema for the exact base profile and machine-readable field contract.
Profile fields
| Group | Configures | Mutation boundary |
|---|---|---|
display, window | Screen, available area, DPR, orientation, outer size, viewport | Most geometry is dynamic; color depth is creation-only. |
identity | User agent, platform, Client Hints metadata | Dynamic; does not install another Chrome implementation. |
hardware | Reported CPU count, memory bucket, performance class | Creation-only observations, not physical allocation. |
locale | Languages, Accept-Language reduction, timezone, Intl locale | Languages are dynamic; timezone and Intl locale require a new Context. |
graphics, fonts | Reported adapter/capability and font baseline | Selected values are read-only or reject unsupported customization. |
preferences | Color scheme, reduced motion, DNT | Theme and motion are dynamic; DNT is creation-only. |
network | Connection observations, proxy, cookies, modeled ICE | Proxy and full network environment require a new Context. |
permissions, capabilities | Initial permissions, quota, keyboard layout | Creation-only; unavailable physical backends remain unsupported. |
features | Restrictions on existing exposure flags | Can restrict captured features, not enable uncaptured ones. |
timing | Execution, navigation, and network scale factors | Creation-only; no arbitrary clock epoch injection. |
Mimic.* commands
Send these custom commands through a browser or page CDP session. They supplement standard CDP; they are not a separate public JavaScript SDK.
Mimic.getProfileSchemaconfiguration
Returns the profile JSON Schema, available base profiles, mutability annotations, and limitations.
Mimic.validateProfileconfiguration
Validates and normalizes a profile without creating a Context. Unsupported values appear in diagnostics rather than silently changing behavior.
Mimic.createContextconfiguration
Creates an isolated BrowserContext with its own profile and connection pool.
Mimic.getProfileconfiguration
Returns a defensive projection of the effective Context profile or a target profile including Page overrides.
Mimic.updateProfileconfiguration
Atomically patches dynamic Page fields. A creation-only field rejects the entire patch with requiresNewContext.
Mimic.resetProfileOverridesconfiguration
Restores a Page to its BrowserContext profile baseline.
Mimic.captureSnapshotcapture
Captures current static DOM and available assets from canonical Page state. This is not a screenshot and excludes scripts, embedded frames, and rendered pixels.
Mimic.setViewportpage control
Applies supported viewport changes through the same Page environment used by standard Emulation commands.
Mimic.getCompatibilityMatrixintrospection
Returns generated CDP command/event status, scope notes, and evidence references. Schema presence alone is not semantic support.
Mimic.getStatusdiagnostic
Returns a lightweight snapshot of current Page execution and navigation state for progress monitoring.
Mimic.getDiagnosticsdiagnostic
Returns runtime and navigation diagnostics useful when a workflow stops making progress.
Mimic.getTracediagnostic
Returns retained scheduler, resource, and semantic events for debugging supported workflows.
Mimic.clearTracediagnostic
Clears the retained diagnostic trace for the selected session/Page.
Mimic.cancelExecutionadvanced
Requests cancellation of current Page execution when a client needs to recover from a busy turn.
Mimic.pauseadvanced
Pauses supported Page processing at the runtime control boundary.
Mimic.resumeadvanced
Resumes Page processing after a matching pause.
-32601; invalid parameters return -32602. Known schema methods without implemented semantics return an explicit unsupported error.Native proxies
{
"network": {
"proxy": {
"server": "socks5://127.0.0.1:1080",
"username": "user",
"password": "password"
}
}
}SOCKS5, HTTP, and HTTPS proxy URLs are supported. Keep credentials in separate fields and out of public files. A proxy failure never falls back to a direct connection. Proxy mode disables QUIC and routes resource-loader HTTP(S), including worker fetch; it does not route UDP/WebRTC.
Multiple contexts
const cdp = await browser.target().createCDPSession();
const { diagnostics } = await cdp.send("Mimic.validateProfile", { profile });
const { browserContextId } = await cdp.send("Mimic.createContext", {
profile,
disposeOnDetach: true
});
try {
const { targetId } = await cdp.send("Target.createTarget", {
browserContextId,
url: "about:blank"
});
await cdp.send("Mimic.updateProfile", {
targetId,
patch: { window: { viewportWidth: 900, viewportHeight: 600 } }
});
} finally {
await cdp.send("Target.disposeBrowserContext", { browserContextId });
}Set the complete profile before creating or navigating the target. A Context is a state boundary, not a security sandbox for hostile tenants.
Compatibility boundaries
Mimic models observable browser state without a native rendering pipeline. Use a full browser when pixels are the desired output.
- No screenshots, rendered PDFs, video playback, or Canvas/WebGL pixel output.
- Modeled geometry and input are not complete CSS layout, clipping, rich editing, touch, drag, or arbitrary transforms.
- CDP and Web API coverage is partial. Generated names and wire schema do not imply implemented semantics.
- Compatibility checks describe specific workflows—not every website, client option, or anti-bot decision.
- The CDP endpoint has no authentication; bind it only where trusted clients can reach it.
Troubleshooting
The client cannot connect
Confirm Mimic prints its listening URL, keep the process alive, and use the same HTTP origin in connectOverCDP or browserURL. Avoid exposing the unauthenticated endpoint publicly.
The application loaded but is not ready
The browser load event can precede hydration. Wait for a selector, text, or application state that represents readiness instead of relying only on waitUntil: "load".
A command is unsupported
Query Mimic.getCompatibilityMatrix and reduce the workflow to the command and observable behavior it needs. A command accepted for client initialization may still have an explicit unsupported boundary.
Linux text geometry differs
Install Liberation, DejaVu, or Noto fonts. Exact Windows text metrics require matching legally available reference fonts.
FAQ
Is Mimic headless Chrome?
No. It uses V8 for JavaScript but does not embed or launch Chromium.
Does every website work?
No. Compatibility is actively expanding and depends on the APIs, loading behavior, and interactions a workflow uses.
Can I run untrusted code?
No. Mimic is not a security sandbox, and separate Pages are not hostile-tenant security boundaries.
Is Mimic open source?
Implementation sources remain private. The public overview, benchmarks, and MIT-licensed client examples are available on GitHub. Mimic uses PolyForm Shield 1.0.0.