Previous: (heks-linux wezterm), Up: API
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.
Default value:
"uBlock0@@raymondhill.net"
Default value:
"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
Default value:
#t
Default value:
#f
Default value:
#t
Default value:
#f
Default value:
()
Default value:
#f
Default value:
#t
Default value:
#f
Default value:
("/root/.zen" "/root/.var/app/app.zen_browser.zen/.zen" "/root/.var/app/app.zen_browser.zen/zen")
Default value:
"user.js"
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
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.
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
Render one preference as a user_pref line, without its newline.
(zen-pref-line "zen.tabs.vertical" #t)
⇒ user_pref("zen.tabs.vertical", true);
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.
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