Unofficial Linux build of OpenAI Codex Desktop. The official Codex Desktop app is macOS-only — this project converts the upstream macOS Codex.dmg into a runnable Linux Electron app, ships native .deb / .rpm / .pkg.tar.zst packages plus a Nix flake, and includes a local auto-updater that rebuilds future Linux packages from newer upstream DMGs.
Before opening a pull request, please read CONTRIBUTING.md.
Optional Linux-only additions live in linux-features/. Use them for integrations that are useful for some users but should not become mandatory core patches. Copy linux-features/features.example.json to the git-ignored linux-features/features.json before building; enabled features are applied during the install/build pipeline. See linux-features/README.md for the feature contract.
| Distro / family | Package manager | Format produced | Notes |
|---|---|---|---|
| Debian, Ubuntu, Pop!_OS, Mint, Elementary | apt |
.deb |
Managed Node.js runtime is bundled; no distro Node.js package is required |
| Fedora 41+ | dnf5 |
.rpm |
|
| Fedora < 41 | dnf |
.rpm |
|
| openSUSE Tumbleweed / Leap | zypper |
.rpm |
Uses zypper --no-gpg-checks install for the local rebuild |
| Arch, Manjaro, EndeavourOS | pacman |
.pkg.tar.zst |
|
| NixOS / Nix | flake | runnable directly | nix run github:ilysenko/codex-desktop-linux |
Anything systemd-based should work for the optional auto-updater service (systemd --user). The launcher targets Wayland with XWayland first (better Electron popup positioning); pure Wayland sessions fall through to --ozone-platform-hint=auto. X11 is fully supported.
| Feature | Status | Notes |
|---|---|---|
| Standard Codex Desktop UI | ✅ always | Chats, browser, files, MCP plugins |
Auto-updater (codex-update-manager) |
✅ always | Detects newer upstream DMGs, rebuilds + installs locally |
Native packaging (.deb / .rpm / .pkg.tar.zst) |
✅ always | One-shot make package picks your distro |
| Linux tray + warm-start handoff | ✅ always | Single-instance lock, second-instance window focus |
GUI install prompts (kdialog / zenity) |
✅ if installed | Falls back to interactive terminal prompt |
| Linux browser annotations | ✅ always | Stored-anchor screenshots, isolated marker rendering |
| Chrome plugin native host | ✅ always | Auto-installs the upstream Chrome plugin plus Linux native-messaging support for Chrome, Brave, and Chromium |
| Linux Computer Use | MCP backend registers by default; the in-app UI is opt-in. Supports screenshots, accessibility, window targeting, and input synthesis | |
Server-gated features (e.g. gpt-5.5) |
🟡 server-side | OpenAI rolls per-account, not project-controlled. Building a fresh package does not unlock these. |
The generated app and native packages bundle a managed Linux Node.js runtime. You do not need a distro nodejs / npm package for normal installs, Browser Use, Codex CLI install/update, or local auto-update rebuilds.
The Codex CLI is still required at runtime. The first launch can install or update @openai/codex with the bundled npm, or you can manage the CLI yourself.
On some systems (e.g. hardened Linux setups), /tmp may be mounted with noexec, preventing the rust installer and bundled Node.js runtime from executing.
Workaround:
mkdir -p ~/tmp/codex-work ~/tmp/codex-cache
export TMPDIR=~/tmp/codex-work
export XDG_CACHE_HOME=~/tmp/codex-cache
# run install steps in this shellThe fastest path: install deps, build the local app, build the native package, install it.
git clone https://github.com/ilysenko/codex-desktop-linux.git
cd codex-desktop-linux
bash scripts/install-deps.sh
make build-app
make package # auto-detects deb / rpm / pacman
make install # installs the newest package from dist/make package picks the format that matches your distro. make install then runs the right dpkg -i / dnf install / zypper install / pacman -U against the freshly built artifact.
nix run github:ilysenko/codex-desktop-linuxThe flake handles dependencies and patches Electron for NixOS. A GitHub Actions bot refreshes the upstream Codex.dmg and recursive Nix payload hashes in main; if you hit a hash mismatch right after an upstream release, wait for the next bot run and retry.
nix develop github:ilysenko/codex-desktop-linux enters a dev shell with the required tooling.
Linux Computer Use is an opt-in plugin that lets Codex inspect and control desktop apps on Linux through a native Rust MCP backend (codex-computer-use-linux). It is designed and maintained by @avifenesh and supports:
- app listing and accessibility trees via AT-SPI
- screenshots through GNOME Shell DBus or XDG Desktop Portal
- window listing and focusing on GNOME, KWin/Plasma, Hyprland, and i3
- keyboard, text, click, scroll, and drag input through
ydotool
# Debian / Ubuntu
sudo apt install ydotool
# Some Ubuntu releases package the daemon separately:
sudo apt install ydotoold
# Fedora
sudo dnf install ydotool
# Arch
sudo pacman -S ydotool
# openSUSE
sudo zypper install ydotoolydotool needs /dev/uinput access. The usual setup is to run ydotoold, add your user to the input group, then re-login:
sudo systemctl enable --now ydotoold
sudo usermod -a -G input "$USER"Some distros install /usr/bin/ydotoold without a service unit. If systemctl enable --now ydotoold fails, create or install a distro-appropriate unit. If doctor reports ydotool_socket: Permission denied, make sure the socket is usable by users in the input group.
A working XDG Desktop Portal implementation is needed if you are not on GNOME — xdg-desktop-portal-kde for KDE Plasma, xdg-desktop-portal-wlr for sway / Hyprland, or your distro's preferred portal backend for i3. GNOME ships a working portal by default.
Once Computer Use is visible in the Codex UI, ask the LLM:
Check whether Linux Computer Use is ready
You can also invoke the backend binary directly:
./codex-app/resources/plugins/openai-bundled/plugins/computer-use/bin/codex-computer-use-linux doctor
./codex-app/resources/plugins/openai-bundled/plugins/computer-use/bin/codex-computer-use-linux setup # enables GNOME accessibility
./codex-app/resources/plugins/openai-bundled/plugins/computer-use/bin/codex-computer-use-linux apps # lists running apps via AT-SPI
./codex-app/resources/plugins/openai-bundled/plugins/computer-use/bin/codex-computer-use-linux windows # lists targetable windows
./codex-app/resources/plugins/openai-bundled/plugins/computer-use/bin/codex-computer-use-linux screenshotBy default the MCP backend registers, but the Codex Desktop sidebar does not surface the Computer Use controls. If you want to use it through the in-app UI, opt in by setting one of:
# Ad-hoc, for a single build:
CODEX_LINUX_ENABLE_COMPUTER_USE_UI=1 make build-app
# Persistent (also picked up by the auto-updater on future rebuilds):
mkdir -p ~/.config/codex-desktop
echo '{"codex-linux-computer-use-ui-enabled": true}' > ~/.config/codex-desktop/settings.jsonEither path enables the in-app controls on subsequent builds. To opt back out, unset the env var and remove or set the settings flag to false.
If you'd like to test the backend without affecting your default install, the side-by-side dev variant builds a separate app under a different ID and webview port:
make build-dev-app
make run-dev-appOverride the dev identity with DEV_APP_ID, DEV_APP_NAME, and CODEX_WEBVIEW_PORT if needed.
The native package installs a companion systemd --user service named codex-update-manager.
- It checks upstream
Codex.dmgon daemon startup, every 6 hours, and in the background on app launch when stale. - When a new DMG is available, it rebuilds a local native package with
/opt/codex-desktop/update-builder. - If Codex Desktop is open, the final install waits until Electron exits.
- The updater runs unprivileged and uses
pkexeconly for the final package install. - Codex CLI checks are best-effort and launcher-scoped. Set
CODEX_SYNC_CLI_PREFLIGHT=1when debugging launch-time CLI preflight.
Inspect the live service and runtime files with:
systemctl --user status codex-update-manager.service
codex-update-manager status --json
sed -n '1,160p' ~/.local/state/codex-update-manager/state.json
sed -n '1,160p' ~/.local/state/codex-update-manager/service.logIf a rebuilt update installs but the previous retained package was better, close Codex Desktop and run:
codex-update-manager rollbackRollback uses the last retained known-good package and refuses to run when no rollback package is available.
Runtime files live in standard XDG locations:
~/.config/codex-update-manager/config.toml
~/.local/state/codex-update-manager/state.json
~/.local/state/codex-update-manager/service.log
~/.cache/codex-update-manager/
~/.cache/codex-desktop/launcher.log
~/.local/state/codex-desktop/app.pid
You need:
python3,7z(or7zz),curl,unzip,make,g++- Rust toolchain (
cargo) for thecodex-update-managerandcodex-computer-use-linuxcrates, including the Chrome extension host binary
The installer downloads a managed Linux Node.js runtime into codex-app/resources/node-runtime and uses it for node, npm, and npx during the build. Existing nvm, asdf, Volta, NodeSource, or nodejs.org tarball installs are still fine, but they are no longer required for this project.
The easiest setup is the bundled bootstrap:
bash scripts/install-deps.shIt auto-detects apt, dnf5, dnf, pacman, or zypper, installs system packages, and bootstraps Rust through rustup when needed.
On apt-based systems, install-deps.sh can still bootstrap NodeSource Node.js for users who want a system Node.js toolchain:
bash scripts/install-deps.sh # full host bootstrap
NODEJS_MAJOR=24 bash scripts/install-deps.sh # choose a different optional system Node lineUbuntu-family p7zip-full can be too old for newer APFS DMGs, so install-deps.sh bootstraps 7zz into ~/.local/bin by default.
# Fedora 41+
sudo dnf install python3 7zip curl unzip @development-tools
# Fedora < 41
sudo dnf install python3 p7zip p7zip-plugins curl unzip
sudo dnf groupinstall 'Development Tools'
# openSUSE
sudo zypper install python3 p7zip-full curl unzip
sudo zypper install -t pattern devel_basis
# Arch / Manjaro
sudo pacman -S --needed python p7zip curl unzip zstd base-devel
# Rust toolchain (any distro)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shThis produces codex-app/ from the upstream DMG and writes the Linux launcher to codex-app/start.sh:
make build-app # downloads upstream DMG
make build-app DMG=/path/to/Codex.dmg # use a local copy
make run-app # launches the generated appEquivalent direct commands:
./install.sh # default: download or reuse cached DMG
./install.sh /path/to/Codex.dmg # use a specific DMG
./install.sh --fresh # remove existing install dir + cached DMG
./codex-app/start.sh # run after buildmake build-app downloads Electron headers while rebuilding native modules, then downloads a Linux Electron runtime. If the runtime download from GitHub is slow or blocked, use a mirror:
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ \
make build-appELECTRON_HEADERS_URL is passed to @electron/rebuild --dist-url and must provide both node-v<version>-headers.tar.gz and the matching SHASUMS256.txt.
After make build-app, build a native package from codex-app/ with the format you need:
| Format | Build command | Output | Install |
|---|---|---|---|
| Debian | make deb or ./scripts/build-deb.sh |
dist/codex-desktop_*.deb |
sudo dpkg -i dist/codex-desktop_*.deb |
| RPM (Fedora / openSUSE) | make rpm or ./scripts/build-rpm.sh |
dist/codex-desktop-*.x86_64.rpm |
sudo dnf install dist/codex-desktop-*.rpm (Fedora) or sudo zypper install dist/codex-desktop-*.rpm (openSUSE) |
| Arch (pacman) | make pacman or ./scripts/build-pacman.sh |
dist/codex-desktop-*.pkg.tar.zst |
sudo pacman -U dist/codex-desktop-*.pkg.tar.zst |
| Auto-detect | make package && make install |
matches your distro | handled by make install |
Override the package version with PACKAGE_VERSION=YYYY.MM.DD.HHMMSS+commitish ./scripts/build-*.sh.
The packaging scripts only repackage what's already in codex-app/. They do not download or extract the DMG themselves.
Native packages bundle the managed Node.js runtime and do not hard-depend on distro nodejs / npm. Packages still pull in polkit (or policykit-1 on older Debian/Ubuntu) plus pkexec for privileged update installs.
After installing a native package:
make service-enable # enable + start the systemd --user service
make service-status # systemctl --user status
codex-update-manager status --jsonmake service-enable is not meant for an unpackaged repo-only run unless you've already installed the package into the system.
make help
make check
make test
make build-updater
make build-app
make run-app
make build-dev-app
make run-dev-app
make deb
make rpm
make pacman
make package # auto-detect distro
make install # install latest dist/ artifact
make service-enable
make service-status
make clean-dist
make clean-state| Problem | Solution |
|---|---|
Error: write EPIPE |
Run start.sh directly instead of piping output |
| Blank window | Check whether the configured webview port is already in use: ss -tlnp | grep -E '5175|5176' |
ERR_CONNECTION_REFUSED on the webview port |
The webview HTTP server failed to start. Ensure python3 works and the configured port is free |
| Stuck on Codex logo splash | Check ~/.cache/codex-desktop/launcher.log. If webview origin validation failed, another process is probably serving the configured webview port or the extracted content/webview/ bundle is incomplete |
CODEX_CLI_PATH error |
Reopen the app to retry the automatic CLI install flow, or install manually with npm i -g @openai/codex / npm i -g --prefix ~/.local @openai/codex |
| Electron hangs while CLI is outdated | Re-run the launcher and check ~/.cache/codex-desktop/launcher.log plus ~/.local/state/codex-update-manager/service.log. Best-effort CLI preflight will warn if the automatic refresh fails |
| GPU / Vulkan / Wayland errors | Under Wayland with DISPLAY available, the launcher uses --ozone-platform=x11 for window-positioning compatibility. Otherwise it uses --ozone-platform-hint=auto. GPU sandbox / compositing are disabled by default |
| Window flickering | GPU compositing is disabled by default. If flickering persists, try ./codex-app/start.sh --disable-gpu to fully disable GPU acceleration |
| Sandbox errors | The launcher already sets --no-sandbox |
| Stale install / cached DMG | ./install.sh --fresh removes the existing install dir and re-downloads |
| Computer Use plugin invisible in UI | Ensure you enabled the Computer Use UI. If it is enabled and still hidden, the OpenAI per-account rollout may not be available |
Computer Use doctor reports ydotool not running |
sudo systemctl enable --now ydotoold and add your user to the input group |
Computer Use doctor reports ydotool_socket: Permission denied |
The daemon socket is root-only. Adjust the ydotoold service so /tmp/.ydotool_socket becomes root:input with 0660 permissions |
ConnectTimeoutError for www.electronjs.org during @electron/rebuild |
Re-run make build-app; the installer now uses https://artifacts.electronjs.org/headers/dist for Electron headers by default |
| Computer Use AT-SPI tree empty | Run codex-computer-use-linux setup to flip GNOME accessibility on, then restart the target app |
codex-update-manager keeps running after package removal |
systemctl --user disable --now codex-update-manager.service once in the affected session, then confirm /opt/codex-desktop is gone |
install.shextractsCodex.dmgwith7z/7zz- It auto-detects the Electron version from upstream metadata, falling back to a pinned constant
- It extracts and patches
app.asar(Linux File Manager integration, tray, single-instance handoff, browser-annotation fixes, Computer Use platform gate, Linux opaque background, etc.) — every patch fail-soft, with regex-driven needles - It rebuilds native Node modules (
better-sqlite3,node-pty) for Linux via@electron/rebuild - It downloads the matching Linux Electron runtime (cached under
~/.cache/codex-desktop/electron/) - It writes the Linux launcher into
codex-app/start.sh(body sourced fromlauncher/start.sh.template) scripts/build-{deb,rpm,pacman}.shpackagescodex-app/into a native artifact- The installed package provides
codex-update-managerplus asystemd --userservice unit - The updater watches for newer upstream DMGs and rebuilds future Linux packages locally
The installer replaces the macOS Electron binary with a Linux build, recompiles native modules, and removes macOS-only pieces such as sparkle.
The launcher serves extracted webview assets from content/webview/ on 127.0.0.1 (5175 by default, 5176 for the dev app), validates the origin, then starts Electron. Warm-start launches hand off actions such as --new-chat over a Unix-domain socket instead of spawning a second app process.
Native-package-only launcher behavior, such as desktop-entry hints and update-manager startup, lives in packaging/linux/codex-packaged-runtime.sh.
The current evaluation for a future Rust replacement of the local webview server lives in docs/webview-server-evaluation.md.
After changing installer, packaging, or updater logic:
bash -n install.sh scripts/lib/*.sh launcher/start.sh.template scripts/build-deb.sh scripts/build-rpm.sh scripts/build-pacman.sh scripts/install-deps.sh
node --check scripts/patch-linux-window-ui.js
for file in scripts/patches/*.js; do node --check "$file"; done
node --check scripts/ci/validate-patch-report.js
node --test scripts/patch-linux-window-ui.test.js
node --test linux-features/*/test.js
bash tests/scripts_smoke.sh
cargo check -p codex-update-manager
cargo test -p codex-update-manager
cargo check -p codex-computer-use-linux
cargo test -p codex-computer-use-linux
make packageFor package metadata checks, run the format-specific commands that are available on your system:
dpkg-deb -I dist/codex-desktop_*.deb
dpkg-deb -c dist/codex-desktop_*.deb | sed -n '1,40p'
make rpm
./scripts/build-pacman.sh
pacman -Qip dist/codex-desktop-*.pkg.tar.zst
pacman -Qlp dist/codex-desktop-*.pkg.tar.zst | sed -n '1,40p'codex-update-manager current crate version: 0.7.1
SemVer policy:
- patch for fixes, docs, and maintenance-only updates
- minor for compatible feature additions
- major for incompatible CLI, persisted-state, or install-flow changes
See CHANGELOG.md for per-version detail.
This is an unofficial community project. Codex Desktop is a product of OpenAI. This tool does not redistribute any OpenAI software; it automates the conversion process that users perform on their own copies.
MIT