Skip to main content
Rustwright — a drop-in replacement for Playwright

A Rust rewrite of Playwright, a popular browser automation library. Rustwright is interoperable with Playwright but runs on an in-process Rust CDP engine — 2.55× faster and 70% less memory (no Node driver), with no Playwright automation fingerprint. Alpha; Chromium-only.

status: alpha tests license: MIT Python 3.9–3.14 + 3.15 pre-release CPython 3.15 support is verified on 3.15.0rc1 and remains pre-release; CI tracks 3.15-dev until GA. npm Chromium only Discord PyPI downloads npm downloads crates.io downloads rustwright-core downloads gem downloads NuGet downloads Maven Central


What is Rustwright?

Rustwright is a browser automation library for Python and Node.js that keeps the Playwright API you already know but drives Chromium from a native Rust engine speaking raw Chrome DevTools Protocol — no driver subprocess in the path.

playwright-python:  your code ──pipe──► Node driver ──CDP──► Chromium
rustwright:         your code ────────── raw CDP ──────────► Chromium

Quickstart

Rustwright is interoperable with Playwright — install it, change one import, and your existing code runs on the Rust engine.

Python

pip install rustwright
python -m rustwright install chromium
- from playwright.sync_api import sync_playwright
+ from rustwright.sync_api import sync_playwright

  with sync_playwright() as p:
      browser = p.chromium.launch(headless=True)
      page = browser.new_page()
      page.goto("https://example.com")
      print(page.title())
      browser.close()

Node.js (experimental)

Install from npm:

npm install rustwright

The Node binding drives an existing Chromium/Chrome — point Rustwright at it with RUSTWRIGHT_CHROMIUM, CHROME, or CHROMIUM. Prefer to build from source? git clone the repo and run npm install && npm run build in node/.

- import { chromium } from 'playwright';
+ import { chromium } from 'rustwright';

  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
  await browser.close();

See the network-independent examples/quickstart.js example. After building the Node binding from source, run it from the repository root with node examples/quickstart.js.

Only a subset of the API surface is bridged — see Limitations.

CLI (agent-focused)

Install the native rustwright-cli with one command:

curl -fsSL https://raw.githubusercontent.com/Skyvern-AI/rustwright/main/install.sh | sh

Then drive a persistent Chromium session from your shell or an agent loop:

rustwright-cli open https://example.com
rustwright-cli snapshot          # compact page tree with @eN refs
rustwright-cli click @e1
rustwright-cli close

See cli/README.md for the full command surface. For a Model Context Protocol server, use the standalone rustwright-mcp package.

Why Rustwright?

Rustwright vs playwright-python live demo
  • No Node driver subprocess. playwright-python launches and pipes to a bundled Node driver. Rustwright's engine is native — the browser-control code runs in-process.
  • Raw CDP, in Rust. A from-scratch async CDP client — not a wrapper around another automation library.
  • No Playwright automation fingerprint. The driver never loads, so its signatures never appear. See Automation detection.
  • Trusted input by default. Clicks and typing go through real CDP input events (Input.dispatchMouseEvent), not synthetic element.click() DOM calls. Untrusted DOM shortcuts are opt-in only.
  • Cross-origin iframes (OOPIF). Auto-attaches out-of-process iframe targets with flattened CDP sessions and routes frame_locator() across origins.
  • One engine, two languages. The same Rust core backs the Python and Node bindings.

How it works

One Rust core — an async CDP client built on Tokio (WebSocket, with opt-in Unix-pipe transport) — talks to Chromium directly, and thin PyO3 (Python) and napi-rs (Node) bindings expose it in-process. The two-line diagram above is the entire architecture.

Already have a Chromium/Chrome binary? Point Rustwright at it with RUSTWRIGHT_CHROMIUM, CHROME, or CHROMIUM.

Browser automation for AI agents

Give an agent or shell script a browser through compact accessibility snapshots with element refs (e1, e2, …), instead of raw HTML or screenshots. Refs are session-scoped, never reused, and best-effort rather than a security boundary; snapshots include page values but mask password fields.

MCP server — give your agent a browser

rustwright-mcp is a native Rust MCP server (no Python or Node runtime in the serving path) that gives any MCP client browser_* tools over stdio, with compact accessibility snapshots and inline PNG screenshots. It lives in mcp/ and is the canonical Rustwright MCP server.

Install

From source (needs a Rust toolchain):

cargo install --git https://github.com/Skyvern-AI/rustwright rustwright-mcp

This installs the server binary as rustwright-mcp. An npm package (rustwright-mcp, prebuilt binaries via npx rustwright-mcp) is on the way.

If Chrome or Chromium is already installed, point Rustwright at it with RUSTWRIGHT_CHROMIUM (or CHROME / CHROMIUM). Otherwise download one with pip install rustwright && python -m rustwright install chromium.

Fastest path

Claude Code
claude mcp add rustwright -- rustwright-mcp
Claude Desktop

Open ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows, then use:

{
  "mcpServers": {
    "rustwright": {
      "command": "rustwright-mcp"
    }
  }
}
Any MCP client
{
  "mcpServers": {
    "rustwright": {
      "command": "rustwright-mcp"
    }
  }
}
If... Do this
You already have Chrome/Chromium Set RUSTWRIGHT_CHROMIUM (or CHROME / CHROMIUM) to its executable in the server's env.
You do not have a browser installed pip install rustwright && python -m rustwright install chromium — the server finds the downloaded browser automatically.
Screenshots are too large to inline Tune RUSTWRIGHT_MCP_SCREENSHOT_MAX_BYTES; oversized captures fall back to a temp-file path instead of inline image content.

See mcp/README.md for the full tool list and configuration. Setting up via an AI agent? Tell it to fetch https://raw.githubusercontent.com/Skyvern-AI/rustwright/HEAD/mcp/README.md and follow it.

The earlier Python MCP server is deprecated: it stays in place until the native server reaches full tool parity, but new capabilities land in mcp/ only.

CLI — drive a browser from your shell

Drive one persistent Chromium session straight from the rustwright command, with no application code.

Try it in 60 seconds

pip install rustwright
python -m rustwright install chromium

rustwright open example.com
rustwright snapshot
rustwright click e1001
rustwright close
  • snapshot shows refs; act by ref, then use the fresh snapshot returned after the action.
  • Add --json for one JSON object per command when scripting.
  • Use --session NAME for named browser sessions.

See the agent interface guide for every verb, flag, and security detail.

Remote browsers (Skyvern)

Rustwright drives browsers — but you still need somewhere to run them. Skyvern (the team behind Rustwright) offers hosted Browser Sessions as a paid service that funds this project.

Features:

  • Persistent cloud browsers — logins, cookies, and tab state carry across runs
  • Configurable timeouts — 5 minutes to 24 hours (60 min default)
  • Proxies in 21 countries
  • Live view — watch and interact with the session in the Skyvern Cloud UI

Each session returns a browser_address CDP endpoint that Rustwright connects to like any remote Chromium (sessions bill while open).

Use chromium.connect_over_cdp() for every remote Chromium connection. BrowserType.connect() is not a CDP alias and does not support Playwright run-server endpoints. See the remote-browser guide for migration steps, endpoint diagnostics, security guidance, and the pinned Open WebUI compose recipe.

Get started:

  1. Make an account at app.skyvern.com
  2. Grab your API key from Settings
  3. pip install skyvern
import asyncio
from rustwright.async_api import async_playwright
from skyvern import Skyvern

async def main():
    session = await Skyvern(api_key="<SKYVERN_API_KEY>").create_browser_session()

    async with async_playwright() as p:
        browser = await p.chromium.connect_over_cdp(session.browser_address)
        page = await browser.new_page()
        await page.goto("https://example.com")

asyncio.run(main())

Remote sessions are Python-only for now — Rustwright's Node binding doesn't support connect_over_cdp yet (it's on the Roadmap).

Automation detection

Because Rustwright never loads Playwright's Node driver, it never emits the automation signatures that ship with it:

  • No Playwright driver signatures — no __playwright__binding__ / utility-world globals, no driver bootstrap. The backend reports playwright_driver: "none".
  • No Runtime.enable on the default path — a normal launch + navigate never enables the CDP Runtime domain, closing the Runtime.enable console-serialization leak behind isAutomatedWithCDP. (Console/page-error/binding opt-ins still enable it lazily — detectable by design.)
  • Headless identity normalized by default — launches with --disable-blink-features=AutomationControlled, rewrites HeadlessChrome/ → Chrome/ in the UA and client hints, and installs a navigator.webdriver cleanup init script.

Local fingerprint runs — default Playwright failed webdriver/headless checks that Rustwright passed; these are local diagnostics, not a guarantee:

Probe Result
SannySoft ✅ Clean
BrowserScan ✅ Clean
DeviceAndBrowserInfo ✅ Clean (after the Runtime-domain cleanup)
CreepJS ⚠️ Detects headless

Benchmarks

The headline numbers are local diagnostics, not yet capped-CI evidence. On speed, one dev-host run (warm browser, 5 iterations) won 16 of 17 case means:

Run Cases Rustwright playwright-python Speedup
Local dev host (warm browser, 5 iterations) 17 5,256 ms 13,418 ms 2.55×

Treat it as a diagnostic, not a launch claim — it is not capped-Docker/CI evidence. Methodology: BENCHMARK.md.

On memory, a form-fill diagnostic recorded the client library's footprint at 133.5 MiB for playwright-python (Python + Node driver) versus 40.6 MiB for Rustwright (no driver) — about 70% less; a separate async-concurrency diagnostic measured ~66% less on the same client-stack basis. Both cover the part the library controls — Chromium-dominated whole-process memory is roughly equal — and both are demo-grade diagnostics, not capped-CI evidence.

Alternatives

Rustwright playwright-python Puppeteer Patchright
API Playwright-shaped (Py + Node) Official Python Playwright JS/TS Puppeteer Playwright drop-in fork
Engine / transport Rust core, raw CDP Python → Node driver Node over CDP Patched PW driver
In-process engine (no driver subprocess) ✅ ❌ bundled Node driver ✅ Node is the runtime ❌ Playwright-style driver
Browsers Chromium only Chromium, Firefox, WebKit Chrome, Firefox Chromium-based
Default input Trusted CDP events Browser-level Browser / CDP Playwright + stealth
Cross-origin iframes OOPIF (alpha) Mature Frame APIs Inherits Playwright
Playwright fingerprint No Yes n/a Patched
Maturity 🟠 Alpha 🟢 Mature 🟢 Mature 🟡 Focused fork

Rustwright's lane: a Rust CDP engine under the Playwright API, for Chromium.

Limitations

See LIMITATIONS.md for detail.

  • Alpha — API shape covered; full behavioral parity not yet proven.
  • API coverage — ~96% of Playwright's Python sync API (515 of 536 methods; 411 exercised by the shared parity registry); the async API provides 488 of 536. Full report: docs/PARITY.md.
  • Chromium only — Firefox and WebKit error explicitly.
  • Node bindings are early — a subset of the surface is bridged (launch, newPage, goto, click, fill, title, textContent, evaluate, screenshot, close); contexts, routing, tracing, and locators are Python-only for now.
  • Async concurrency (Python) — the async API wraps the sync engine via threads; recommended for ≈≤25 concurrent workflows/process, not high fan-out.
  • OOPIF — residual gaps in non-main-frame JSHandle follow-ups and drag/screenshot/bounding-box.
  • Automation detection is partial — 3 of 4 public fingerprint targets clean in local runs (CreepJS still detects headless). No undetectability promise.

Roadmap

  • Kotlin binding — idiomatic Kotlin wrapper (Kotlin/JVM can already consume the Java FFM binding)
  • Grow the new language bindings beyond the alpha subset (contexts, routing, locators)
  • Rustwright MCP server — expose browser automation as tools for MCP-compatible AI agents (mcp/)
  • CI / Testbox-backed benchmark evidence
  • Broaden the Node.js surface (contexts, routing, locators)
  • Close remaining OOPIF gaps

Recently shipped:

  • Language bindings (alpha) — Go, Java, C#/.NET, Ruby, and PHP over a shared C ABI, plus a native Rust API (bindings/CONTRACT.md); cross-language equivalence gated in CI
  • Python package published to PyPI
  • Node.js binding published to npm
  • Native async engine over the Tokio CDP core
  • OOPIF auto-attach with flattened CDP sessions
  • 515/515 shared parity suite green against real Playwright
  • Runtime.enable console-serialization leak closed on the default path

Firefox and WebKit are not planned — Rustwright is deliberately Chromium-only.

Contributing

Rustwright is Rust + Python + Node. cargo builds the engine; maturin develop --release installs the Python package; cd node && npm run build builds the Node addon; the Python suite exercises the engine against real Chromium. Full Docker gate: 1,046 tests pass (6 skipped), plus 515/515 shared parity cases run against real Playwright; CI (test.yml) runs a fast representative subset on every PR.

See CONTRIBUTING.md for build details and the code-layout reality.

Project status

Rustwright is an early alpha from Skyvern, developed in the open. If the architecture resonates, give it a ⭐.

Questions, ideas, or want to help? Join the Skyvern community on Discord.

Telemetry

Rustwright sends one engine_launched event per process to PostHog with the Rustwright version, operating system, and CPU architecture. It sends no URLs or page content.

Events carry a random installation ID, generated without using the hostname, username, or MAC address, stored at ~/.cache/rustwright/telemetry_id (or the $XDG_CACHE_HOME/%LOCALAPPDATA% equivalent) so events from the same installation can be counted together. Delete the file to reset it. Events are marked personless, and GeoIP enrichment is disabled at the event level. The request, like any HTTPS request, exposes the sender's IP address to PostHog, but Rustwright does not store the IP address in the event payload.

To opt out:

export DISABLE_TELEMETRY=1   # or DO_NOT_TRACK=1

License

MIT © 2026 Ikonomos Inc (dba Skyvern)

Built with 🦀🐉 and a lot of CDP frames · Skyvern-AI/rustwright

Metadata

Release files for rustwright 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rustwright 0.3.0
File Size Uploaded Provenance
rustwright-0.3.0.tar.gz 4.5 MB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for rustwright 0.3.0
File
rustwright-0.3.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
rustwright-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
rustwright-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
rustwright-0.3.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details
rustwright-0.3.0-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details

Total release size: 22.5 MB

Release files / rustwright-0.3.0.tar.gz

Download URL rustwright-0.3.0.tar.gz
Size 4.5 MB
Tags Source
SHA-256 checksum
How to use checksums
be74d806f29310abc5c96c8219b70a08854baaa4d1c852ce890260679d7a92d5
BLAKE2b-256 checksum
How to use checksums
1fe32436454e6811760fc9db6149465348fcbd4f775258c146743ccf5063d25a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / rustwright-0.3.0-cp38-abi3-win_amd64.whl

Download URL rustwright-0.3.0-cp38-abi3-win_amd64.whl
Size 4.0 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
818031c88a41db6c3148a94a3d12151cd5053cec3d17cff181b09f1c0f541087
BLAKE2b-256 checksum
How to use checksums
a420fa6eee05ca1d1147304bc875c0c902298bcead3ebf432734c0b805e096f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / rustwright-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rustwright-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.6 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
5c026d4e3789382fae009a5c96ec708351fc45e41f672529722ca9e1ce5fe142
BLAKE2b-256 checksum
How to use checksums
6f34295c595979877f60feba9e92c43d83202be09189c371101465347b4ddb73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / rustwright-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL rustwright-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.4 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
01d04e7b85e48bf76053afdf9392fc8b5c902483581fb726c05347048e00bc74
BLAKE2b-256 checksum
How to use checksums
bf60d45c3c321013eb120d2cb2371043afccc6a063fec3dc1440681e67894121
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / rustwright-0.3.0-cp38-abi3-macosx_11_0_arm64.whl

Download URL rustwright-0.3.0-cp38-abi3-macosx_11_0_arm64.whl
Size 3.4 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c3cc4579e22be68c578b2bfd335030f7b1e7a49248ddd0887793f81b752a1946
BLAKE2b-256 checksum
How to use checksums
b06585694f745b2c7558bdf286e1a47d9d9eebe19463d1f03d72a2b5a5183f81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / rustwright-0.3.0-cp38-abi3-macosx_10_12_x86_64.whl

Download URL rustwright-0.3.0-cp38-abi3-macosx_10_12_x86_64.whl
Size 3.5 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
2b64e59bf32c08bbeb286f4aa8a3c50c57ddbb3a42d96d86b1a4fc37c012f2fc
BLAKE2b-256 checksum
How to use checksums
2fb3a58c00a908ce2e25ca4ecfedbd15cf5970eb7180c141e515f0c664721a06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Security for rustwright 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for rustwright-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page