Docs

Electron / Chromium Version — Research Notes

Research + delivery summary for a class of failure where a modern website’s JavaScript bundle calls a browser API that Tranquil’s embedded Chromium is too old to have. Says what breaks, why, what shipped as a stopgap, and the upstream state of a real fix.

The trigger

Opening openai.com in a browser tab rendered a blank page. The console showed:

Uncaught TypeError: URL.parse is not a function
    at Module.iS [as getDocument] (…)

The page’s framework bundle called URL.parse(...), hit undefined, threw, and the uncaught error aborted hydration — so the whole page failed to render. This is not site-specific: any site whose bundle uses URL.parse / URL.canParse breaks the same way.

Root cause: Chromium is behind the API

Tranquil (like Pulsar upstream) ships Electron 30.5.1, which embeds Chromium 124. The static URL.parse() and URL.canParse() methods only shipped in Chromium 126[^1]. So the API a modern site assumes is present simply doesn’t exist in our engine yet.

VersionChromiumHas URL.parse?
Tranquil (now)Electron 30.5.1124
URL.parse landed126

The version is pinned in package.json as both electronVersion and the electron devDependency — Tranquil inherits it verbatim from Pulsar.

Upstream Pulsar is on the same version

Checked against upstream live master (commit as of 2026-07-07): upstream Pulsar is also on Electron 30.5.1 / Chromium 124 — identical to Tranquil. There is no newer Pulsar release to pull that would fix this.

There is interest but nothing merged. Open, unmerged Electron-bump PRs on pulsar-edit/pulsar:

PRTargetChromiumClears 126?
#1600Electron 32.3.3~128
#1202Electron 34.0.1~132
#1450Electron 40.6.0~140

Any of these would make URL.parse native. All have sat open for weeks/months — Electron bumps are painful in the Atom/Pulsar lineage because of native-module rebuilds, the deprecated @electron/remote, and jQuery/atom-space-pen-views-era webview code that the browser package still leans on.

What shipped: a main-world polyfill

A targeted shim closes the gap without waiting on the Electron bump. It lives in the browser webview preload and polyfills the two missing URL statics with spec-matching behavior (return a URL or null instead of throwing).

The context-isolation wrinkle

The browser webview runs with contextIsolation: "on", so the preload executes in an isolated world — a global it defines there is not visible to the page’s scripts. The polyfill therefore injects into the page’s main world via webFrame.executeJavaScript. Because preload code runs before any page script, the polyfill is installed before a site’s bundle executes and reaches for URL.parse.

Where it lives

  • tranquil-browserresources/bp-client.js — the webview preload. The polyfill is a webFrame.executeJavaScript call at the top of the file, guarded by typeof URL.parse !== 'function' so it becomes a no-op once the engine has the native method (i.e. after a future Electron bump — the shim can then be removed cleanly).

Constraints / follow-ups

  • The polyfill only covers URL.parse / URL.canParse. A Chromium-124 webview has other modern-API gaps too. If more sites break with X is not a function, that’s the same class of problem — the real long-term fix is the Electron bump, not an ever-growing pile of shims.
  • A preload change requires a full app restart to take effect (preload scripts are read when the webview is created, not per-navigation).
  • Revisit and delete the shim when Tranquil moves to Electron 32+ (Chromium ≥ 126), whether by tracking one of the upstream bump PRs or bumping independently.

Verified

  • With the polyfill in place, openai.com loads and renders correctly in a browser tab. ✅ (confirmed live)

[^1]: URL.parse() static method — Baseline / browser availability shows first support in Chromium 126 (mirrored in Node.js 22.1). URL.canParse() landed slightly earlier (Chromium 120) but is polyfilled alongside for safety.