Browser Commander

August 2, 2026 ยท View on GitHub

A universal browser automation library with a unified API across multiple browser engines and programming languages. The key focus is on stoppable page triggers - ensuring automation logic is properly mounted/unmounted during page navigation.

Available Implementations

LanguagePackageStatus
JavaScript/TypeScriptbrowser-commandernpm
Rustbrowser-commandercrates.io
Pythonbrowser-commanderPyPI

Engine Support

LanguagePrimary enginesNotes
JavaScript/TypeScriptPlaywright, PuppeteerUses the official Node.js packages directly.
RustChromiumoxide, Playwright, PuppeteerChromiumoxide is native Rust/CDP. Playwright and Puppeteer run through a Node.js bridge to the official packages. Fantoccini remains available as an engine type for compatibility, but managed launch is not implemented yet.
PythonPlaywright, SeleniumUses the official Python integrations and supports attaching to an existing Chrome-family browser over CDP.

See docs/feature-parity.md for the cross-language feature matrix and docs/case-studies/issue-51/README.md for the implementation notes.

All three implementations can attach to a running Chrome-family browser over CDP or find and start an installed Chrome, Edge, Brave, or Chromium with a safe, dedicated automation profile before attaching. Use launchRealBrowser() in JavaScript and launch_real_browser() in Python or Rust.

All implementations also expose installed-browser profile discovery and local cookie import for Chrome, Edge, Brave, Chromium, and Firefox. Cookie values are returned in the automation-engine shape and cached locally with owner-only permissions so platform credential stores are touched at most once per TTL.

Core Concept: Page State Machine

Browser Commander manages the browser as a state machine with two states:

+------------------+                      +------------------+
|                  |   navigation start   |                  |
|  WORKING STATE   | -------------------> |  LOADING STATE   |
|  (action runs)   |                      |  (wait only)     |
|                  |   <-----------------  |                  |
+------------------+     page ready       +------------------+

LOADING STATE: Page is loading. Only waiting/tracking operations are allowed. No automation logic runs.

WORKING STATE: Page is fully loaded (30 seconds of network idle). Page triggers can safely interact with DOM.

Page Trigger Lifecycle

The library provides a guarantee when navigation is detected:

  1. Action is signaled to stop (AbortController.abort())
  2. Wait for action to finish (up to 10 seconds for graceful cleanup)
  3. Only then start waiting for page load

This ensures:

  • No DOM operations on stale/loading pages
  • Actions can do proper cleanup (clear intervals, save state)
  • No race conditions between action and navigation

Getting Started

For installation and usage instructions, see the documentation for your preferred language:

Testing Layer

The JavaScript package now exposes browser-commander/tests, a test-anywhere-based browser test layer with Playwright/Puppeteer engine matrices, fixture cleanup, retries, failure artifacts, historical duration tracking, longest-first ordering, and balanced shard planning. See js/README.md#browser-commander-tests and js/examples/browser-commander-tests.example.js.

Architecture

See js/src/ARCHITECTURE.md for detailed architecture documentation.

Generated Documentation

The Documentation workflow builds JavaScript JSDoc output and Rust cargo doc output into one artifact. On main, the same artifact is published with GitHub Pages when Pages is enabled for the repository.

Local commands:

cd js && npm run docs:api
cd rust && cargo doc --no-deps --all-features

License

UNLICENSE