Previous: , Up: API  


1.26 (heks-linux zen)

Renders user.js into every Zen Browser profile it can find.

Zen is a Firefox fork, so its configuration is the Firefox one: a user.js in the profile is read on every start and overrides whatever the previous session stored in prefs.js. That is exactly what makes a declarative browser configuration possible - and exactly why a setting changed in Zen’s own settings page comes back after a restart.

The profiles are not at a fixed path. A native install keeps them under ~/.zen, the Flatpak build under ~/.var/app/app.zen_browser.zen/.zen (with some versions using .../zen), and every profile has a random prefix such as abc123.Default (release). Rather than guess, zen-profile-dirs scans those roots for directories that contain a prefs.js, which is the file Firefox itself creates when it starts a profile for the first time. A machine that has never launched Zen therefore has nothing to configure, and the installer says so instead of inventing a profile Zen would ignore.

This module only states the deltas. Zen ships a prefs/privatefox set that already locks telemetry, studies and crash upload off, disables its AI features, and turns off sponsored suggestions; those are not repeated here. What is added is the layout Heks wants (vertical tabs), the prefs Zen leaves open (tracking protection, no prefetching or speculative connections), the Browser Toolbox (with an opt-in external source editor), and the two prefs that let a side-loaded extension start enabled.

The two prefs that are known to break real sites - Firefox’s fingerprinting protection and HTTPS-Only mode - are available but off: this is a daily driver, and a blank page or an unreachable site is worse than a fingerprint.

uBlock Origin is installed by dropping the signed AMO build into <profile>/extensions/uBlock0@raymondhill.net.xpi. Firefox treats an XPI in the profile as a side-loaded add-on; extensions.autoDisableScopes is set to 0 so it is enabled on the next start instead of arriving disabled behind a prompt. A policies.json would be the other way to install it, but the Flatpak ships its own read-only policy file next to the binary, so the profile is the one place both installs share.

The Browser Toolbox prefs (devtools.chrome.enabled and devtools.debugger.remote-enabled) are powerful and slightly risky: the connection prompt is deliberately left on, and the devtools theme follows the active palette. The external source editor is opt-in: Firefox would launch the path from inside its own process, and the Flatpak sandbox has its own /usr and no permission to start host programs, so a host emacsclient only works for a native install.

Because this is a user.js, local changes belong in $XDG_CONFIG_HOME/heks-linux/zen-settings.scm; zen-extra-prefs is appended last and wins over every generated preference.

1.26.1 Parameters

Parameter: zen-adblock-extension-id

Default value:

"uBlock0@@raymondhill.net"
Parameter: zen-adblock-install-url

Default value:

"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
Parameter: zen-adblock?

Default value:

#t
Parameter: zen-compact-mode?

Default value:

#f
Parameter: zen-devtools?

Default value:

#t
Parameter: zen-external-editor

Default value:

#f
Parameter: zen-extra-prefs

Default value:

()
Parameter: zen-fingerprinting-protection?

Default value:

#f
Parameter: zen-hardening?

Default value:

#t
Parameter: zen-https-only?

Default value:

#f
Parameter: zen-profile-roots

Default value:

("/root/.zen" "/root/.var/app/app.zen_browser.zen/.zen" "/root/.var/app/app.zen_browser.zen/zen")
Parameter: zen-user-js-filename

Default value:

"user.js"

1.26.2 Procedures

Procedure: heks-linux-zen-settings

Return the full Zen configuration as a list of (name . value) pairs.

The layout is always present; the compact-mode, hardening, fingerprinting, HTTPS-Only, devtools and adblock blocks are added according to their parameters, and zen-extra-prefs comes last so a local override wins.

(assoc-ref (heks-linux-zen-settings) "zen.tabs.vertical")
⇒ #t
Procedure: install-zen-config

Install the Zen Browser configuration into every profile that exists.

Local overrides are read from $XDG_CONFIG_HOME/heks-linux/zen-settings.scm first. Each profile gets a fresh user.js; when zen-adblock? is set, a missing uBlock Origin XPI is downloaded as well. A machine where Zen has never started has no profile to write to, so the task logs that instead of creating one Zen would ignore.

Procedure: serialize-zen-value value

Return value as the JavaScript literal a user_pref call takes.

Booleans become true and false, numbers lose their Scheme punctuation and strings are quoted. Zen prefs are scalars only, so anything else is a programming error rather than something to render.

(serialize-zen-value #t)
⇒ true
Procedure: zen-pref-line name value

Render one preference as a user_pref line, without its newline.

(zen-pref-line "zen.tabs.vertical" #t)
⇒ user_pref("zen.tabs.vertical", true);
Procedure: zen-profile-dirs

Return every existing Zen profile directory.

Each root in zen-profile-roots is scanned for directories that contain a prefs.js; that file is the marker Firefox itself writes when a profile has been started, so directories such as storage or Crash Reports are skipped without needing a name convention.

Procedure: zen-user-js

Return the user.js file for Zen as a string.

The file starts with a generated-file header, then one user_pref call per setting, in the order of heks-linux-zen-settings.


Previous: (heks-linux wezterm), Up: API