Skip to main content
The browser runs on its own. Every persona setting is a command-line switch, so any tool that can start Chromium can start Apostate. This page lists what the packages do that you then do yourself.

Find the binary

apostate path prints the executable and downloads the browser first if it is missing. On macOS the executable is Chromium.app/Contents/MacOS/Chromium inside the install directory. Installation lists the cache paths and how to use a browser you installed yourself. The archives hold the browser, its crash handler, the SwiftShader and ANGLE libraries, and the locale and resource files. None of the four archives has a chromedriver.

Run it

apostate run downloads the browser if it is missing and adds the Widevine module, then starts the browser with the switches you give it, unchanged. It adds no seed, locale, timezone or --no-first-run, so the command below passes them:
Running the path from apostate path directly does the same without those two steps. Add --fingerprint-explain to print the machine and exit instead. Switches lists every switch. The first tab of a launch without a driver shows Chromium’s “Google API keys are missing” bar, which takes 56 pixels from innerHeight. Google Chrome never shows it. Set GOOGLE_API_KEY=no, GOOGLE_DEFAULT_CLIENT_ID=no and GOOGLE_DEFAULT_CLIENT_SECRET=no in the browser’s environment, or open a second tab and use that. A launch with --no-sandbox shows a bar for that flag instead, so leave it out where the sandbox runs. Known gaps has the measurements.

Keep the machine

With --user-data-dir and no --fingerprint, the first launch draws a machine and stores its seed in DIR/apostate/identity, and later launches with that directory present it again. With neither switch, every launch draws a new machine while Chromium’s default directory keeps the cookies. Seeds and identity covers both.

What the packages add

A launch through the Python or Node package passes more than the persona switches. Without the package, add what you need: The Node package’s launchProcess() does the package’s part, GeoIP, environment and Xvfb included, and starts the binary with no driver attached. From 0.4.4 it also passes --no-first-run and --no-default-browser-check. On 0.4.3, add both to args for a headed launch. Node covers it.

Headed without a display

On a Linux host with no display, run the browser under xvfb-run. It needs the xauth package as well as xvfb. Pass --no-first-run for a new user data directory.
3840x2160 fits any screen a seed picks. Without xauth, xvfb-run stops with xvfb-run: error: xauth command not found.

Connect over CDP

A client such as Playwright or Puppeteer drives the browser over the Chrome DevTools Protocol, through a pipe or a port.
  • --remote-debugging-pipe passes the protocol over file descriptors 3 and 4 and opens no port. The packages’ drivers use it, and only the process that started the browser can use it.
  • --remote-debugging-port=9222 opens the protocol on 127.0.0.1:9222. Any process on the host can connect to it and control the browser, with no password. Keep the port on 127.0.0.1, and do not forward it to other hosts. --remote-debugging-port=0 picks a free port and writes it to DevToolsActivePort in the user data directory.
The endpoint refuses requests that web pages send. In a test with 0.4.3 on macOS, a fetch from a page on 127.0.0.1 failed with the same TypeError for the open port as for a closed one. Start the browser with a port:
Then connect from another process:
Patchright comes with the Python package. browser.contexts[0] is the profile’s own context. A context from browser.new_context() is off-the-record. defaultViewport: null keeps Puppeteer from resizing the page to 800x600. raw_cdp.py starts the binary with --remote-debugging-port=0, reads the port from DevToolsActivePort and connects. launch-process.mjs does the same through launchProcess().

Other languages

Any Chromium client can start Apostate. Set its executable path to the output of apostate path and add the switches, or start the browser with --remote-debugging-port and connect to it. This applies to chromedp in Go, chromiumoxide in Rust and CDP clients in other languages. Selenium drives Chrome through chromedriver, which no Apostate archive includes. ChromeDriver supports the Chrome major version it was built for, so it has to be version 152.