0xc000022070/zen-browser-flake

Community-driven Nix Flake for the Zen browser

Nix

1,017

1,328 commits

updated Oct 15, 2026

See the code

README

Zen Browser

This is a nix flake for the Zen browser.

Features

A flake for Zen Browser that lets you fine-tune more than other flakes.

Installation

Just add it to your NixOS flake.nix or home-manager:

inputs = {
  zen-browser = {
    url = "github:0xc000022070/zen-browser-flake";
    inputs = {
      # IMPORTANT: To ensure compatibility with the latest Firefox version, use nixpkgs-unstable.
      nixpkgs.follows = "nixpkgs";
      home-manager.follows = "home-manager";
    };
  };
  # ...
}

[!NOTE] Beta Branch: To keep the flake input only sync with beta updates, use inputs.zen-browser.url = "github:0xc000022070/zen-browser-flake/beta".

Integration

[!IMPORTANT] Use the twilight package to guarantee reproducibility, the artifacts of that package are re-uploaded to this repository. However, if you don't agree with that and want to use the official artifacts, use twilight-official.

Home Manager

{
  # home.nix
  imports = [
    inputs.zen-browser.homeModules.beta
    # or inputs.zen-browser.homeModules.twilight
    # or inputs.zen-browser.homeModules.twilight-official
  ];

  programs.zen-browser = {
    enable = true;
    setAsDefaultBrowser = true;
  };
}

Then build your Home Manager configuration:

$ home-manager switch

Check the Home Manager Reference and my rice here! :)

With environment.systemPackages or home.packages

To integrate Zen Browser into your NixOS/Home Manager configuration, add the following to your environment.systemPackages or home.packages:

# options are: 'x86_64-linux', 'aarch64-linux' and 'aarch64-darwin'

inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".default # beta
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".beta
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".twilight
# IMPORTANT: this package relies on the twilight release artifacts from the
# official zen repo and those artifacts are always replaced, causing hash mismatch
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".twilight-official

# you can even override the package policies
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".default.override {
  extraPolicies = {
      DisableAppUpdate = true;
      DisableTelemetry = true;
      # more and more
  };
}

Afterwards you can just build your configuration

$ sudo nixos-rebuild switch # or home-manager switch

Start the browser

$ zen-beta # or zen-twilight

Configuration Examples

See the examples/ directory for standalone configuration examples:

ExampleDescription
01-basic-home-manager.nixMinimal Home Manager setup
02-policies-configuration.nixSystem policies (policies.json)
02a-policies-preferences.nixLocked preferences (policies.Preferences)
02b-settings-preferences.nixUser settings (profiles.*.settings)
03-policies-package-override.nixPackage-level policy override
04-extensions.nixFirefox addons, managed storage config
04b-extensions-rycee.nixFirefox addons via rycee.nix, ext storage
05-mods-installation.nixZen theme store mods
06-search-engines.nixCustom search engines
07-bookmarks.nixBookmark organization
08-containers.nixMulti-container setup
09-spaces-themes.nixSpaces with themes
10-pinned-tabs.nixPinned tabs, folders, space-scoped pins
11-keyboard-shortcuts.nixKeyboard shortcut overrides
12-userchrome-css.nixuserChrome CSS customization
13-complete-setup.nixFull real-world configuration
14-native-messaging.nixNative messaging hosts (1Password, etc.)
15-joined-tabs.nixJoined tabs configuration
16-environment-variablesEnvironment variables (themes, etc.)
17-live-foldersLive folders (Issues, etc)
18-space-routingSpace routing
19-extension-buttonsExtension buttons pinned to the toolbar
20-sine-modsSine mods (Linux only)

Home Manager Reference

This module is based on Home Manager's mkFirefoxModule. Refer to the examples above for common patterns.

Core options:

  • enable (boolean): Enable Home Manager config
  • setAsDefaultBrowser (boolean): Set Zen as default for URLs and file types

[!IMPORTANT] macOS users need to configure programs.zen-browser.darwinDefaultsId first. See home-manager options.

Configuration Layers

Three distinct configuration layers, stored differently:

LayerFileStorageUser Can Override
System Policies02-policies-configuration.nixpolicies.jsonNo (enforced)
Locked Preferences02a-policies-preferences.nixpolicies.jsonNo (enforced)
User Settings02b-settings-preferences.nixprefs.jsYes (defaults)

Profile Configuration

Profiles support many sub-options. See examples directory for:

Browser State Management

[!NOTE] Close Zen browser before home-manager switch if you declare:

  • Any spaces (with or without spacesForce)
  • Any pins (with or without pinsForce)
  • Any containers (with or without containersForce)
  • Any keyboardShortcuts
  • Any extensionButtons

If you only declare simple options like policies/extensions/bookmarks, rebuilding while Zen is open is ok.

Spaces, pins, and containers are stored in zen-sessions.jsonlz4 (Mozilla LZ4 compressed JSON). The activation script:

  1. Checks if Zen is running via lsof path/to/profile/.parentlock—skips the update with a warning (activation still succeeds) if browser is open
  2. Decompresses zen-sessions.jsonlz4 from LZ4 to JSON
  3. Modifies it with jq to apply your declared config
  4. Recompresses back to LZ4
  5. Restores backup on any failure

Browser must be closed because the file is locked in memory while Zen runs. With pinsForce = true, pinsForceAction (default demote) selects whether undeclared pinned or essential tabs are removed or demoted to normal tabs; with pinsForce = false, no changes are made to pins.

Showcase

Here are some user configurations that showcase different setups using this flake:

1Password

Zen has to be manually added to the list of browsers that 1Password will communicate with. See this wiki article for more information. To enable 1Password integration, you need to add the browser identifier to the file /etc/1password/custom_allowed_browsers.

environment.etc = {
  "1password/custom_allowed_browsers" = {
    text = ''
      .zen-wrapped
    ''; # or just "zen" if you use unwrapped package
    mode = "0755";
  };
};

Native Messaging

To enable communication between the browser and native applications, you can use the following configuration pattern.

With Home Manager

Check the Home Manager Reference.

With package override

{
  home.packages = [
    (
      inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".default.override {
        nativeMessagingHosts = [pkgs.firefoxpwa];
      }
    )
  ];
}

Troubleshooting

Missing configuration after update

  1. The release 1.18.6b changed the configuration location. Please move your configuration from ~/.zen to ~/.config/zen and restart the browser

    mkdir -p ~/.config/zen
    mv ~/.zen/* ~/.config/zen/
    rmdir ~/.zen
    

    Then change every occurrence of ".zen" to ".config/zen" in:

    • .config/zen/<profile_name>/extensions.json
    • .config/zen/<profile_name>/pkcs11.txt
    • .config/zen/<profile_name>/chrome_debugger_profile/pkcs11.txt

    Then run zen in safe mode once and close it (it will perform the required migrations):

    # or zen-twilight
    zen-beta --safe-mode
    
  2. Please check that you're using the wrapped version of the package. The -unwrapped variants should not be used directly. Instead, they should be wrapped with wrapFirefox or custom wrappers.

Alternatively, you can review this discussion in the official Zen Browser repository.

The requested URL returned error: 404

This usually happens when the Zen team deletes a beta release from the official repository. They do this to keep only stable artifacts available. See #105 and #112 for further context.

You can either revert your nix input update or wait until CI refreshes sources.json.

Zen not seeing my GPU

Make sure that you update your flake.lock as to sync up nixpkgs version. Or make zen follow your system nixpkgs by using inputs.nixpkgs.follows = "nixpkgs" (assuming your nixpkgs input is named nixpkgs).

Check No WebGL context for details.

1Password constantly requires password

You may want to set policies.DisableAppUpdate = false; in your policies.json file. See #48.

Contributing

Before contributing, please make sure that your code is formatted correctly by running

$ nix fmt

LICENSE

This project is licensed under the MIT License.

linux
macos
nix
nix-flake
nix-modules
nixos
zen
zen-browser

0xc000022070/zen-browser-flake

Community-driven Nix Flake for the Zen browser

Nix

1,017

1,328 commits

updated Oct 15, 2026

See the code

README

Zen Browser

This is a nix flake for the Zen browser.

Features

A flake for Zen Browser that lets you fine-tune more than other flakes.

Installation

Just add it to your NixOS flake.nix or home-manager:

inputs = {
  zen-browser = {
    url = "github:0xc000022070/zen-browser-flake";
    inputs = {
      # IMPORTANT: To ensure compatibility with the latest Firefox version, use nixpkgs-unstable.
      nixpkgs.follows = "nixpkgs";
      home-manager.follows = "home-manager";
    };
  };
  # ...
}

[!NOTE] Beta Branch: To keep the flake input only sync with beta updates, use inputs.zen-browser.url = "github:0xc000022070/zen-browser-flake/beta".

Integration

[!IMPORTANT] Use the twilight package to guarantee reproducibility, the artifacts of that package are re-uploaded to this repository. However, if you don't agree with that and want to use the official artifacts, use twilight-official.

Home Manager

{
  # home.nix
  imports = [
    inputs.zen-browser.homeModules.beta
    # or inputs.zen-browser.homeModules.twilight
    # or inputs.zen-browser.homeModules.twilight-official
  ];

  programs.zen-browser = {
    enable = true;
    setAsDefaultBrowser = true;
  };
}

Then build your Home Manager configuration:

$ home-manager switch

Check the Home Manager Reference and my rice here! :)

With environment.systemPackages or home.packages

To integrate Zen Browser into your NixOS/Home Manager configuration, add the following to your environment.systemPackages or home.packages:

# options are: 'x86_64-linux', 'aarch64-linux' and 'aarch64-darwin'

inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".default # beta
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".beta
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".twilight
# IMPORTANT: this package relies on the twilight release artifacts from the
# official zen repo and those artifacts are always replaced, causing hash mismatch
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".twilight-official

# you can even override the package policies
inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".default.override {
  extraPolicies = {
      DisableAppUpdate = true;
      DisableTelemetry = true;
      # more and more
  };
}

Afterwards you can just build your configuration

$ sudo nixos-rebuild switch # or home-manager switch

Start the browser

$ zen-beta # or zen-twilight

Configuration Examples

See the examples/ directory for standalone configuration examples:

ExampleDescription
01-basic-home-manager.nixMinimal Home Manager setup
02-policies-configuration.nixSystem policies (policies.json)
02a-policies-preferences.nixLocked preferences (policies.Preferences)
02b-settings-preferences.nixUser settings (profiles.*.settings)
03-policies-package-override.nixPackage-level policy override
04-extensions.nixFirefox addons, managed storage config
04b-extensions-rycee.nixFirefox addons via rycee.nix, ext storage
05-mods-installation.nixZen theme store mods
06-search-engines.nixCustom search engines
07-bookmarks.nixBookmark organization
08-containers.nixMulti-container setup
09-spaces-themes.nixSpaces with themes
10-pinned-tabs.nixPinned tabs, folders, space-scoped pins
11-keyboard-shortcuts.nixKeyboard shortcut overrides
12-userchrome-css.nixuserChrome CSS customization
13-complete-setup.nixFull real-world configuration
14-native-messaging.nixNative messaging hosts (1Password, etc.)
15-joined-tabs.nixJoined tabs configuration
16-environment-variablesEnvironment variables (themes, etc.)
17-live-foldersLive folders (Issues, etc)
18-space-routingSpace routing
19-extension-buttonsExtension buttons pinned to the toolbar
20-sine-modsSine mods (Linux only)

Home Manager Reference

This module is based on Home Manager's mkFirefoxModule. Refer to the examples above for common patterns.

Core options:

  • enable (boolean): Enable Home Manager config
  • setAsDefaultBrowser (boolean): Set Zen as default for URLs and file types

[!IMPORTANT] macOS users need to configure programs.zen-browser.darwinDefaultsId first. See home-manager options.

Configuration Layers

Three distinct configuration layers, stored differently:

LayerFileStorageUser Can Override
System Policies02-policies-configuration.nixpolicies.jsonNo (enforced)
Locked Preferences02a-policies-preferences.nixpolicies.jsonNo (enforced)
User Settings02b-settings-preferences.nixprefs.jsYes (defaults)

Profile Configuration

Profiles support many sub-options. See examples directory for:

Browser State Management

[!NOTE] Close Zen browser before home-manager switch if you declare:

  • Any spaces (with or without spacesForce)
  • Any pins (with or without pinsForce)
  • Any containers (with or without containersForce)
  • Any keyboardShortcuts
  • Any extensionButtons

If you only declare simple options like policies/extensions/bookmarks, rebuilding while Zen is open is ok.

Spaces, pins, and containers are stored in zen-sessions.jsonlz4 (Mozilla LZ4 compressed JSON). The activation script:

  1. Checks if Zen is running via lsof path/to/profile/.parentlock—skips the update with a warning (activation still succeeds) if browser is open
  2. Decompresses zen-sessions.jsonlz4 from LZ4 to JSON
  3. Modifies it with jq to apply your declared config
  4. Recompresses back to LZ4
  5. Restores backup on any failure

Browser must be closed because the file is locked in memory while Zen runs. With pinsForce = true, pinsForceAction (default demote) selects whether undeclared pinned or essential tabs are removed or demoted to normal tabs; with pinsForce = false, no changes are made to pins.

Showcase

Here are some user configurations that showcase different setups using this flake:

1Password

Zen has to be manually added to the list of browsers that 1Password will communicate with. See this wiki article for more information. To enable 1Password integration, you need to add the browser identifier to the file /etc/1password/custom_allowed_browsers.

environment.etc = {
  "1password/custom_allowed_browsers" = {
    text = ''
      .zen-wrapped
    ''; # or just "zen" if you use unwrapped package
    mode = "0755";
  };
};

Native Messaging

To enable communication between the browser and native applications, you can use the following configuration pattern.

With Home Manager

Check the Home Manager Reference.

With package override

{
  home.packages = [
    (
      inputs.zen-browser.packages."${pkgs.stdenv.hostPlatform.system}".default.override {
        nativeMessagingHosts = [pkgs.firefoxpwa];
      }
    )
  ];
}

Troubleshooting

Missing configuration after update

  1. The release 1.18.6b changed the configuration location. Please move your configuration from ~/.zen to ~/.config/zen and restart the browser

    mkdir -p ~/.config/zen
    mv ~/.zen/* ~/.config/zen/
    rmdir ~/.zen
    

    Then change every occurrence of ".zen" to ".config/zen" in:

    • .config/zen/<profile_name>/extensions.json
    • .config/zen/<profile_name>/pkcs11.txt
    • .config/zen/<profile_name>/chrome_debugger_profile/pkcs11.txt

    Then run zen in safe mode once and close it (it will perform the required migrations):

    # or zen-twilight
    zen-beta --safe-mode
    
  2. Please check that you're using the wrapped version of the package. The -unwrapped variants should not be used directly. Instead, they should be wrapped with wrapFirefox or custom wrappers.

Alternatively, you can review this discussion in the official Zen Browser repository.

The requested URL returned error: 404

This usually happens when the Zen team deletes a beta release from the official repository. They do this to keep only stable artifacts available. See #105 and #112 for further context.

You can either revert your nix input update or wait until CI refreshes sources.json.

Zen not seeing my GPU

Make sure that you update your flake.lock as to sync up nixpkgs version. Or make zen follow your system nixpkgs by using inputs.nixpkgs.follows = "nixpkgs" (assuming your nixpkgs input is named nixpkgs).

Check No WebGL context for details.

1Password constantly requires password

You may want to set policies.DisableAppUpdate = false; in your policies.json file. See #48.

Contributing

Before contributing, please make sure that your code is formatted correctly by running

$ nix fmt

LICENSE

This project is licensed under the MIT License.

linux
macos
nix
nix-flake
nix-modules
nixos
zen
zen-browser

Significant stargazers

(top 24 of 43)

Marc Jakobi

297 followers · starred May 2026

Antoine Cotten

156 followers · starred May 2026

Alejandro

181 followers · starred Jul 2026

Fausto Núñez Alberro

70 followers · starred May 2025