Skip to main content
Each release publishes browser archives for Linux x64, Linux arm64, macOS arm64 and Windows x64 on GitHub Releases. 0.5.1 is built on Chromium 155.0.8059.31. Releases up to 0.4.4 are built on Chromium 152.0.7977.83. The Python package (apostate on PyPI) and the Node package (@heretic-tech/apostate on npm) are released with the same version number when their code changes.

v0.5.1

Released 30 September 2026. Browser archives for all four platforms, and Python and Node packages 0.5.1. There is no 0.5.0 release: its build served no WebGPU adapter on a Linux host with no GPU, and 0.5.1 is that build with the fix.
  • Chromium 155. The browser is Chromium 155.0.8059.31. The User-Agent and client hints report Chrome 155, as current stable Chrome does. The packages install and accept only this build.
  • Seeds. A seed presents the same machine as in 0.4.4. The machine is keyed on fixed version values, not on the running build, so the update does not re-draw it; only the version in the User-Agent moves.
  • GPU families. The WebGL and WebGPU values are the ones measured on Chrome 152. The ANGLE, Dawn and Chromium code that produces them changed between 152 and 155 in nothing a page reads: the new WebGPU features in 155 are experimental, and stock Chrome does not expose them.
  • Patches. The patch that gave incognito sessions Chrome’s static storage quota is removed, because Chromium 155 does this by default. The synthetic camera, the software WebGPU check and the first window’s placement follow Chromium 155’s interfaces.
  • Windows build. The Windows archive is built with Windows SDK 10.0.28000.2270, which Chromium 155 requires.
  • Measured on development builds of 155.0.8059.12. The offline tier of the test suite gives the same result for all 367 tests on Linux x64 as 0.4.4. On an M4 Max, FingerprintJS Pro did not flag the Windows or macOS persona, and flagged the Linux persona as it does in 0.4.4 (Linux personas score as an anomaly).
  • MCP server. @heretic-tech/apostate-mcp 0.2.0 uses the Node package 0.5.1, so it launches the Chrome 155 build.
  • Captures. The capture receiver admits Chrome 155 captures, and capture/take-capture.sh fetches the Chrome for Testing build of the pinned version.

v0.4.4

Released 28 September 2026. Browser archives for all four platforms, and Python and Node packages 0.4.4.
  • Windows on ARM hosts. A Windows persona on an ARM host, such as an Apple silicon Mac, draws a new Qualcomm Adreno family instead of an Intel or NVIDIA one, because it claims the arm architecture and every real Windows-on-ARM machine has an Adreno GPU. The family has three measured models: the Adreno X2-90 (18 cores, 32 GB), X1-85 (12 cores, 32 GB) and X1-45 (8 cores, 16 GB). Windows seeds on ARM hosts present a different machine than in 0.4.3. Seeds on x86 hosts do not change. See ARM hosts.
  • No WebGPU adapter where none was measured. A GPU that returned no WebGPU adapter in its capture, such as the Adreno X1-45 and two Linux NVIDIA cards, now has none on any host. In 0.4.3 the host’s own adapter showed through, so on a Mac such a persona served Apple’s adapter.
  • Windows 11 font names. A Windows persona lists the named instances of Segoe UI Variable and Sitka as Windows does, such as “Segoe UI Variable Display” and “Sitka Small”, and no longer the base names “Segoe UI Variable” and “Sitka”. On a Mac or Linux host the instance names resolve to the installed variable fonts, for CSS families and local() alike. iphey.com flagged the old names as an inconsistent fingerprint (“butterfly”).
  • Node 22. The Node package needs Node 22 or later, and its engines field says so. It calls Promise.withResolvers, which Node 20 lacks, so on Node 20 every GeoIP lookup of 0.4.3 failed.
  • Dark themes. Both packages turn off Playwright’s prefers-color-scheme: light emulation, so a page reads the persona’s own theme. On 0.4.3, pass color_scheme="null" in Python or call page.emulateMedia({ colorScheme: null }) in Node. See prefers-color-scheme in the 0.4.3 packages.
  • Timezones. Both packages refuse a timezone that is not an IANA zone name, before launch. Python raises ConfigurationError and Node throws RangeError. In 0.4.3 an unknown name went into TZ, and a page’s Intl timezone read undefined.
  • GeoIP warning. The warning for a failed lookup says the persona uses en-US and the host’s timezone. In 0.4.3 it said the launch keeps the host’s own locale, which was wrong. The reason and the advice are joined without a double period.
  • Python diagnostics. Python launches carry apostate_diagnostics, as Node launches carry apostateDiagnostics. GeoIP warnings are in its ["warnings"] list.
  • Python sync API. Several browsers can be open at once in one thread. They share the thread’s driver, which stops when the last of them closes. In 0.4.3 a second launch() while one is open fails with Sync API inside the asyncio loop.
  • Launch errors. A launch error no longer carries the --apostate-profile value, which holds a proxy credential base64-encoded. The value reads --apostate-profile=<redacted>. In Python, a proxy URL in the error text has its credential replaced with <redacted>, and the rest of the text is kept. In 0.4.3 the text was cut at the first proxy URL, which dropped the browser’s own apostate: refusal line.
  • Sandbox. Both packages keep Chromium’s sandbox on where it can start: macOS, Windows, and Linux as a regular user outside a container, with no seccomp filter and with user namespaces allowed. Playwright otherwise passes --no-sandbox, and a headed window then shows Chromium’s unsupported-flag bar on its first tab, which took 56 pixels from innerHeight. An explicit chromium_sandbox or chromiumSandbox is kept. See A bar on the first tab.
  • Proxy credentials. Both packages count the 4096 limit for a username or password in bytes of UTF-8, as the browser does, and both refuse a malformed escape such as %zz.
  • Timezone case. The Node package refuses a timezone that differs from a zone name only in letter case, such as europe/berlin, as the Python package does. On Windows the Python package depends on tzdata, so it can check names on a host with no tz database.
  • Node first run. Every Node launch passes --no-first-run and --no-default-browser-check. launchProcess() did not, so a headed first launch of a new user data directory could stop at a first-run dialog.
  • Python CLI. apostate run forwards every argument after run to the browser, so apostate run --fingerprint=42 works without a -- separator, as it already did in the Node CLI.
  • Fonts. apostate fonts install windows also installs the Windows 11 Marlett, which the font repository it clones lacks. It reads only that file out of the liblaf/fonts Win11 release zip with HTTP range requests, and installs it only when its SHA-256 matches.
  • Catalogue. The catalogue the packages ship describes the seed as keyed on the version values v0.4.2 used, and names apostate/identity as the file a persistent profile stores its seed in. The browser’s own catalogue is unchanged.
  • Captures. capture/publish-capture.py moves a capture taken through a tunnel into resources/fingerprints/raw/, after removing the headers the tunnel added and re-running the admission checks. scripts/build-anchor.py builds a GPU family from admitted captures.
  • MCP server. A new package in mcp/, @heretic-tech/apostate-mcp 0.1.0, gives an AI agent an Apostate browser with Playwright MCP’s tools. It needs Node 22 or later. MCP server describes it.
  • Test suite. tests/ checks what a page reads from the browser, offline against a local probe page and live against public detector pages, and writes each run to a dated results file. The offline tier and the MCP server’s test run in CI on Linux x64 with the released browser. Test suite describes it, and Results has the published runs from macOS arm64 and Linux arm64.
  • Examples. examples/ holds runnable Python, Node, use-case, agent and Docker examples. Examples lists them.
  • Documentation. This site replaces the Markdown pages in docs/. docs/KNOWN_GAPS.md stays as a pointer, because the 0.4.3 browser’s --fingerprint-explain names it. The repository README and the PyPI and npm READMEs link to the site.

v0.4.3

Released 26 September 2026. Python and Node packages 0.4.3.
  • URLs. A Windows persona parses file paths in URLs as Windows Chrome does. new URL("c:/foo").protocol is file:, where other personas and stock Chromium on Linux and macOS give c:.
  • Seeds. A seed keeps its machine across Chrome updates and catalogue version changes. The machine is keyed on fixed version values, the ones v0.4.2 used, so a v0.4.2 seed presents the same machine in v0.4.3. An edit to a catalogue table still re-draws the choices that table decides.
  • CPU performance. navigator.cpuPerformance follows the persona’s core count and ignores the host’s CPU model, except for a macOS persona on a Mac.
  • Python. viewport=None means no viewport. Playwright had dropped the None and emulated a 1280x720 viewport.

v0.4.2

Released 25 September 2026. Browser archives only. No package was released at this version.
  • Fonts under a Windows persona. Ascent, descent and line gap come from the fonts’ Windows metrics as DirectWrite reads them, including the typo metrics a font asks for. Windows alias and legacy family names resolve, such as Courier, Times, Helvetica, MS Sans Serif and Franklin Gothic. Emoji and symbols fall back to Segoe UI Emoji, Segoe UI Symbol and Cambria Math.
  • Font install. apostate fonts install windows installs only the families of the Windows core font pack, lists the ones still missing, and takes --from DIR to install from a Windows Fonts folder.
  • Locale. --fingerprint-locale with one tag sets only the UI locale, and the language list is Chrome’s own default for that locale. A comma list sets the list exactly. The packages pass the GeoIP locale as one tag.
  • Voices. A persona lists its voices on a host with no speech engine. The Windows sets include the Google network voices desktop Chrome lists, and the en-US Windows set matches two real machines’ 22 voices.
  • WebGPU. GPUAdapterInfo.subgroupMinSize and subgroupMaxSize come from the GPU family instead of the host.
  • Window. A new window fills the persona’s work area, and a Windows persona opens maximized. The packages’ Xvfb display is 3840x2160, so any claimed screen fits.
  • Windows machines. Screen sizes and core counts follow a public corpus of Windows sessions. The taskbar is at the bottom, 40 pixels on Windows 10 and 48 on Windows 11. The 1920x1200 and 2048x1280 screens are gone, and the network is always 4g. These table changes give many seeds a different machine than v0.4.0 gave them.
  • Linux personas on ARM hosts keep navigator.platform as Linux x86_64, as Chrome does on every Linux CPU. The ARM host shows only in the Client Hints architecture.

v0.4.0

Released 23 September 2026. Python and Node packages 0.4.0.
  • Normal profile. launch() opens pages in a normal profile instead of an off-the-record context, on a temporary profile the driver deletes on close. new_context() stays off-the-record, as in Playwright. This needs Patchright 1.55 or Playwright 1.53 or later.
  • Windows system values. A Windows persona serves Windows system colours, Segoe UI for the CSS system fonts, Windows’ system-ui and default fonts, no BarcodeDetector, a 48 kHz AudioContext, the claimed speakers on a host with no sound card, the claimed GPU’s power-efficient codecs and the US Windows keyboard map.
  • CPU architecture. Windows and Linux personas claim the host’s CPU architecture, arm on an ARM host.
  • WebGPU. A host with no GPU serves the claimed adapter instead of none, and every GPU model has a WebGPU adapter. On Linux, requestAdapter() still returns null in headless mode and in a headed launch as root. See WebGPU in headless mode on Linux.
  • Widevine. The packages give the browser a Widevine CDM on first launch, copied from a local Google Chrome or downloaded from Google and checked by SHA-256. The Python CLI adds apostate provision-drm.
  • Linux displays. A headed launch on a Linux host with no display starts its own Xvfb, sized to the persona’s screen, and stops it on close.
  • Fonts. Each persona shows only its platform’s font families. The CLI adds apostate fonts install windows, fonts install macos and fonts export-macos.
  • Removed. The font metric and text raster emulation added in earlier releases, which measured as changing nothing detectors score.
  • Fixes. A Windows persona no longer crashes the browser in enumerateDevices() on a host with no sound card. WebGPU on a host with no GPU keeps the float32-filterable and float32-blendable features. The Python package extracts .tar.zst on Python before 3.14, and the Node package decompresses zstd itself on Node 22.15 and later.

v0.3.0

Released 22 September 2026. Python and Node packages 0.3.0.
  • Windows fonts and voices. The Windows core font pack is the Windows 11 English set, and every persona lists its own platform’s voices, spoken by a real speech provider.
  • Refused switches. Both packages refuse a misspelt --fingerprint* switch, such as --fingeprint-platform, and --fingerprint-noise=false, which turns noise on.
  • Persistent profiles. Both packages refuse a persistent profile on launch() and name launch_persistent_context() instead. The Node package also refuses --user-data-dir and --proxy-server in args, which it had dropped without a word.
  • GeoIP through SOCKS5. The lookup hands the endpoint’s name to the proxy instead of resolving it on the host.
  • Node package. It downloads from its own release, and an extraction failure names the tool that is missing.

v0.2.1

Released 22 September 2026. Python and Node packages 0.2.1.
  • Text. A persona derives sub-pixel text positioning by its own platform’s rule, so a Linux persona on a Mac measures text advances as Linux Chrome does.

v0.2.0

Released 21 September 2026. Node package 0.2.0.
  • Signed macOS build. The macOS bundle is Developer ID signed and notarized.
  • GPUs. A Windows persona can present many more NVIDIA and Intel models, registered on the measured GPU families by PCI device id, including the GeForce RTX 40 series.
  • WebGL. The GPU family’s WebGL limits reach pages on every host backend, Metal included.
  • WebRTC. Behind a SOCKS5 proxy, WebRTC offers only the address families the proxy can relay.
  • Readback noise. --fingerprint-noise, off by default, changes canvas and WebGL readback by one step per channel, seeded by the profile.
  • Extensions. The profile decides whether pages see chrome.runtime from an installed extension.
  • Install. Patchright is a dependency of both packages, so one install is enough. The packages find a browser already on disk before downloading one.

v0.1.0

Released 20 September 2026. Python and Node packages 0.1.0, and 0.1.1. The first public release. It is Chromium 152.0.7977.83 with a composer that builds a whole Windows, macOS or Linux machine from a seed before any other browser process starts.
  • Switches. --fingerprint, --fingerprint-platform, --fingerprint-anchor and --fingerprint-explain, the per-field switches, --fingerprint=host and --apostate-profile.
  • Persistent identity. A launch with --user-data-dir stores its seed in the directory and presents the same machine on every later launch.
  • Locale and timezone. They come from the launch or the host, never from the seed. A composed persona ignores the shell’s locale.
  • Proxies. --proxy-server accepts a credential in the URL. WebRTC relays UDP through a SOCKS5 proxy or opens no UDP socket.
  • Packages. The Python and Node packages download and verify the browser, look up the exit’s locale and timezone, and launch it through Patchright or Playwright. The Node package also drives Puppeteer.
The 0.1.1 packages install the v0.1.0 browser. They fetch the release’s manifest when the package carries none, ship the GeoIP lookup inside the Python package with SOCKS5 support, map every country to a locale, and send a SOCKS proxy credential to the browser instead of the driver.