Nix

July 10, 2026 ยท View on GitHub

Run ChatGPT Desktop for Linux directly with:

nix run github:ilysenko/codex-desktop-linux

The flake handles dependencies and patches Electron for NixOS. A GitHub Actions bot refreshes the upstream Codex.dmg hash and verifies the Nix package outputs in main. If you hit a hash mismatch right after an upstream release, wait for the next bot run and retry.

Codex CLI Requirement

ChatGPT Desktop still needs the Codex CLI at runtime. The Nix package in this repository does not install or maintain the CLI for you; it only needs a working codex binary. Put codex on your user PATH, or set CODEX_CLI_PATH to the exact binary that ChatGPT Desktop should launch.

Relying on PATH alone is fragile: a graphical autostart entry, an application launcher, or a warm-start handoff to an already-running instance may not have your Nix profile on PATH, in which case ChatGPT Desktop fails with Unable to locate the Codex CLI binary. Set CODEX_CLI_PATH .... Pinning the CLI explicitly avoids this. The Home Manager and NixOS modules can do this for you via programs.codexDesktopLinux.cliPackage, which wraps the launcher so CODEX_CLI_PATH is always set.

One direct upstream install path is the npm package:

npm i -g --include=optional @openai/codex

The --include=optional flag ensures npm also installs the Linux platform binary package that the CLI loads at runtime.

Community Nix CLI Packages

If you want a Nix-native CLI setup, one community-maintained option is the sadjow/codex-cli-nix flake. It is not part of this repository and is not maintained by this project or by OpenAI. We do not control its release cadence, build recipe, binary cache, or support policy.

Use it only if that trade-off makes sense for your configuration. Pin it to a tag or commit for reproducibility, review the flake and cache trust settings before using them, and report package/cache-specific issues to that project. Issues in this repository should be limited to ChatGPT Desktop discovering and launching a working CLI binary.

The community flake exposes Nix packages for the native binary and Node.js builds:

nix run github:sadjow/codex-cli-nix/main

For a declarative setup, add the CLI flake as an input:

{
  inputs.codex-cli-nix = {
    # Default branch is `main` on GitHub, not `master`.
    url = "github:sadjow/codex-cli-nix/main";
    inputs = {
      nixpkgs.follows = "nixpkgs";
      flake-utils.follows = "flake-utils";
    };
  };
}

The flake also publishes a third-party Cachix cache for prebuilt binaries. This cache is independent from this repository's codex-desktop-linux cache. Enabling it means trusting substitutes signed by that cache key; omit this step if you prefer local builds.

cachix use codex-cli

For a declarative NixOS cache configuration:

{
  nix.settings = {
    substituters = [ "https://codex-cli.cachix.org" ];
    trusted-public-keys = [
      "codex-cli.cachix.org-1:1Br3H1hHoRYG22n//cGKJOk3cQXgYobUel6O8DgSing="
    ];
  };
}

Then install its package next to ChatGPT Desktop from Home Manager:

{ inputs, pkgs, ... }:
let
  codexCli = inputs.codex-cli-nix.packages.${pkgs.stdenv.hostPlatform.system}.default;
in
{
  home.packages = [
    codexCli
  ];

  programs.codexDesktopLinux = {
    enable = true;
    # Bake CODEX_CLI_PATH into the launcher so the Desktop app always finds this
    # CLI, even when launched from a graphical session that lacks the profile on
    # PATH.
    cliPackage = codexCli;
  };
}

Setting cliPackage wraps the installed ChatGPT Desktop launcher (and its .desktop entry) so it always starts with CODEX_CLI_PATH pointing at the package's codex binary. Because the value is baked into the launcher rather than exported as a session variable, it works for graphical, terminal, and warm-start launches and takes effect on the next app launch โ€” no re-login required. An explicit CODEX_CLI_PATH already in the environment still wins. If you enable remoteControl but leave cliPackage unset, the module reuses remoteControl.package automatically.

For a NixOS module, use the same package in environment.systemPackages instead of home.packages.

If you enable the remote-control service, point it at the same CLI package:

{ inputs, pkgs, ... }:
let
  codexCli = inputs.codex-cli-nix.packages.${pkgs.stdenv.hostPlatform.system}.default;
in
{
  programs.codexDesktopLinux = {
    enable = true;
    remoteControl = {
      enable = true;
      package = codexCli;
    };
  };
}

Pinning github:sadjow/codex-cli-nix to a release tag or commit is recommended for fully reproducible configurations.

If your graphical session does not put the selected profile on PATH, set cliPackage so the launcher is wrapped with CODEX_CLI_PATH:

{
  # Preferred: wrap the launcher so CODEX_CLI_PATH is always set.
  programs.codexDesktopLinux.cliPackage = codexCli;

  # Manual fallback if you are not using the module (needs a re-login to apply):
  # home.sessionVariables.CODEX_CLI_PATH = "${codexCli}/bin/codex";
}

If nix run appears to do nothing, check the launcher log first:

sed -n '1,220p' ~/.cache/codex-desktop/launcher.log

Feature Outputs

Flakes do not include the git-ignored linux-features/features.json opt-in file. Nix therefore keeps the existing cache-friendly feature outputs and also lets module users select Linux features that have been verified to build hermetically.

Remote mobile control:

nix run github:ilysenko/codex-desktop-linux#remote-mobile-control

Computer Use UI plus remote mobile control:

nix run github:ilysenko/codex-desktop-linux#computer-use-ui-remote-mobile-control

Computer Use UI only:

nix run github:ilysenko/codex-desktop-linux#codex-desktop-computer-use-ui

The Home Manager and NixOS modules accept these feature IDs through programs.codexDesktopLinux.linuxFeatures:

Feature IDPurpose
appshotsLinux AppShots capture integration
mcp-helper-reaperCleanup for stale configured MCP helper processes
node-repl-reaperCleanup for leaked Browser Use node_repl helpers
open-target-discoveryLinux terminal, editor, and file-manager discovery
persistent-status-panelPersistent /status panel state
remote-mobile-controlExperimental mobile remote-control host enrollment

The list is validated during module evaluation, then deduplicated and sorted so equivalent configurations produce the same derivation. Features that are not in this Nix allowlist remain available through the regular opt-in feature flow but cannot be selected from a pure flake configuration.

Home Manager / NixOS Module

For a declarative install with the mobile remote-control app-server managed by systemd instead of the Desktop launcher:

{
  imports = [
    inputs.codex-desktop-linux.homeManagerModules.default
  ];

  programs.codexDesktopLinux = {
    enable = true;
    computerUseUi.enable = true;
    remoteMobileControl.enable = true;
    linuxFeatures = [
      "appshots"
      "open-target-discovery"
    ];
    remoteControl.enable = true;
  };
}

remoteMobileControl.enable remains a compatibility shorthand for adding remote-mobile-control to the normalized feature list. computerUseUi.enable remains a dedicated option because it selects the Computer Use UI package path. The existing named package outputs use the same package builder with fixed arguments. Setting programs.codexDesktopLinux.package still selects that package directly and takes precedence over module-driven feature selection.

This installs the selected ChatGPT Desktop package variant and starts a user codex-remote-control.service with:

codex app-server --remote-control --listen unix://

A nixosModules.default export is also available for system-level configurations that prefer a global user unit.

Development Shell

nix develop github:ilysenko/codex-desktop-linux

Cachix

CI can populate a Cachix cache named codex-desktop-linux for flake package outputs. To push to the cache, create it in Cachix and add a repository secret named CACHIX_AUTH_TOKEN with write access.

Users can opt in locally with:

cachix use codex-desktop-linux

The scheduled Populate Cachix workflow builds the default package, feature-specific package variants, and .#installer.