Documentation

Build with Mimic.

Start the local browser runtime, connect a standard automation client over CDP, and configure the observable environment your workflow needs.

Mimic is not a JavaScript SDK. The primary interface is a local CDP endpoint. Use normal Playwright, Puppeteer, or raw CDP calls; the custom 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.

PlatformRuntime requirements
Windows amd64Verified on Windows 11. Run mimic.exe.
Linux amd64glibc 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:9222

Keep 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

FlagDefaultPurpose
--listen127.0.0.1:9222CDP HTTP and WebSocket address.
--chrome152Loaded Chrome compatibility milestone. It does not install Chrome.
--profilenoneJSON environment profile for new contexts.
--browser-modeheadfulChooses the environment profile; it does not open a window.
--enginev8JavaScript engine: v8, quickjs, or goja. Fallbacks do not promise V8 equivalence.
--navigation-timeout0Optional navigation execution cap. Zero waits until completion or cancellation.
--dev-previewfalseEnables 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

GroupConfiguresMutation boundary
display, windowScreen, available area, DPR, orientation, outer size, viewportMost geometry is dynamic; color depth is creation-only.
identityUser agent, platform, Client Hints metadataDynamic; does not install another Chrome implementation.
hardwareReported CPU count, memory bucket, performance classCreation-only observations, not physical allocation.
localeLanguages, Accept-Language reduction, timezone, Intl localeLanguages are dynamic; timezone and Intl locale require a new Context.
graphics, fontsReported adapter/capability and font baselineSelected values are read-only or reject unsupported customization.
preferencesColor scheme, reduced motion, DNTTheme and motion are dynamic; DNT is creation-only.
networkConnection observations, proxy, cookies, modeled ICEProxy and full network environment require a new Context.
permissions, capabilitiesInitial permissions, quota, keyboard layoutCreation-only; unavailable physical backends remain unsupported.
featuresRestrictions on existing exposure flagsCan restrict captured features, not enable uncaptured ones.
timingExecution, navigation, and network scale factorsCreation-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.

params: {} → { schema, baseProfiles, limitations }

Mimic.validateProfileconfiguration

Validates and normalizes a profile without creating a Context. Unsupported values appear in diagnostics rather than silently changing behavior.

params: { profile } → { profile, diagnostics }

Mimic.createContextconfiguration

Creates an isolated BrowserContext with its own profile and connection pool.

params: { profile, disposeOnDetach? } → { browserContextId }

Mimic.getProfileconfiguration

Returns a defensive projection of the effective Context profile or a target profile including Page overrides.

params: exactly one of { browserContextId } or { targetId } → { profile, … }

Mimic.updateProfileconfiguration

Atomically patches dynamic Page fields. A creation-only field rejects the entire patch with requiresNewContext.

params: { targetId, patch } → updated profile result

Mimic.resetProfileOverridesconfiguration

Restores a Page to its BrowserContext profile baseline.

params: { targetId } → effective baseline profile

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.

params: { interrupt? } → snapshot payload

Mimic.setViewportpage control

Applies supported viewport changes through the same Page environment used by standard Emulation commands.

params: page viewport fields → effective viewport

Mimic.getCompatibilityMatrixintrospection

Returns generated CDP command/event status, scope notes, and evidence references. Schema presence alone is not semantic support.

params: {} → generated compatibility inventory

Mimic.getStatusdiagnostic

Returns a lightweight snapshot of current Page execution and navigation state for progress monitoring.

params: {} → current status

Mimic.getDiagnosticsdiagnostic

Returns runtime and navigation diagnostics useful when a workflow stops making progress.

params: {} → diagnostic state

Mimic.getTracediagnostic

Returns retained scheduler, resource, and semantic events for debugging supported workflows.

params: {} → { events, … }

Mimic.clearTracediagnostic

Clears the retained diagnostic trace for the selected session/Page.

params: {} → acknowledgement

Mimic.cancelExecutionadvanced

Requests cancellation of current Page execution when a client needs to recover from a busy turn.

params: command-specific cancellation options → acknowledgement/status

Mimic.pauseadvanced

Pauses supported Page processing at the runtime control boundary.

params: {} → acknowledgement

Mimic.resumeadvanced

Resumes Page processing after a matching pause.

params: {} → acknowledgement
Unknown methods return CDP error -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.