Videos
I managed to run the Codex App on Linux without having access to the source code.
High-level steps:
- Extracted the DMG and unpacked `app.asar`
- Installed the matching Electron version for Linux
- Rebuilt native modules (`node-pty`, `better-sqlite3`)
- Removed macOS-only stuff (like Sparkle)
- Repacked everything and dropped it into Electron
- Added a small workaround because the app thinks it’s in dev mode and tries to hit a Vite server
- Launched it with `--no-sandbox`
Important detail: the app itself is basically just a GUI wrapper. You still need the Codex CLI installed on Linux for it to work.
https://github.com/ilysenko/codex-desktop-linux
I did this on Ubuntu 25.10. I have no idea how well this works on other Linux distros or versions.
If you want to improve it, feel free to make fixes and open pull requests.
I'm wondering if there is anymore information out there on the Linux version of the Codex desktop app. I've signed up on the wait list. I'd love to test this on Linux. Thank you.
/Michael
I got the macOS Codex desktop app (.dmg) running on Ubuntu Linux — here’s the full technical breakdown
I recently experimented with running the macOS-only Codex desktop app on Ubuntu.
Since .dmg isn’t a native Linux package, there’s no direct install path — so I approached this as a cross-platform packaging, runtime, and deep debugging problem.
The core idea
Instead of trying to “install” the DMG, I built a bridge layer:
-
Extract the macOS Electron payload
-
Rebuild Linux-compatible native modules
-
Launch the UI on Linux
-
Correctly wire it to the modern Codex CLI backend
So the final architecture became:
-
UI runtime: Electron app from extracted
asar-unpacked -
Backend agent:
codex app-server(CLI) -
Bridge launcher: Linux script that sets env + connects UI → CLI
-
Config state:
~/.codex/config.tomlcontrolling default model + migrations
Step 1 — Preparing a runnable Linux payload
From the DMG:
-
Extracted the application bundle
-
Unpacked
app.asar→asar-unpacked -
Rebuilt required native Node modules for Linux ABI, notably:
-
better-sqlite3 -
node-pty
-
Without this rebuild, Electron crashed immediately on Ubuntu.
Step 2 — Creating a real Linux launcher
I created:
-
~/.local/bin/codex-dmg-linux→ launcher script -
Desktop entry under
~/.local/share/applications/
The launcher:
-
Reads payload location via
CODEX_DMG_WORKDIR -
Optionally overrides CLI via
CODEX_CLI_PATH -
Sets required env:
-
BUILD_FLAVOR=prod -
NODE_ENV=production -
renderer URL → local webview
-
-
Starts Electron with Linux-safe flags.
At this point, the UI launched successfully on Ubuntu.
Step 3 — The real failure: messages silently didn’t send
No UI errors.
But backend turns failed with:
model_not_found
So this became a runtime / backend investigation, not a UI issue.
Root cause — hidden CLI version skew
I discovered two Codex CLI installations:
-
New CLI → 0.98.0 (supports
gpt-5.3-codex) -
Old CLI → 0.94.0 (pulled in via extension / launcher path)
The desktop app was invoking the old CLI,
so the requested model didn’t exist → model_not_found.
Classic path-resolution / version-skew bug that looks like an account or server issue.
Final fix
-
Patched launcher to use the modern Linuxbrew CLI explicitly
-
/home/linuxbrew/.linuxbrew/bin/codex
-
-
Restored default model:
-
model = "gpt-5.3-codex"
-
-
Removed a migration rule that downgraded 5.3 → 5.2
Verification (end-to-end)
Confirmed correctness at multiple layers:
-
model/listshows gpt-5.3-codex -
Direct inference:codex exec --model gpt-5.3-codex "Reply with one word: ok" → returns
ok -
thread/startvia app-server reports:-
model = gpt-5.3-codex
-
cliVersion = 0.98.0
-
-
Running process confirmed from Linuxbrew path.
Warnings observed but non-blocking:
-
DBus UnitExists
-
Node
url.parsedeprecation -
MCP context provider failure
None affected chat functionality.
Open-source bridge (no proprietary binaries)
Repo:
https://github.com/Mina-Sayed/codex-dmg-linux-bridge
Includes:
-
Launcher script
-
Setup + troubleshooting docs
-
No DMG or proprietary binaries (downloaded separately from official source for licensing reasons).
Engineering time
Total time: ~1 hour 10 minutes.
What used to take days of low-level debugging
can now be compressed into minutes —
if you know how to properly drive AI agents and verify the system end-to-end.
Happy to answer questions or discuss Electron cross-platform quirks,
native module rebuilding, or Codex CLI runtime behavior.
took 15 min yesterday and it's been working flawlessly on my arch/niri system
tldr from codex explaining what it did:
Extracted the macOS Codex.dmg, then extracted app.asar into app_asar/ (Electron app payload) via linux/scripts/extract-dmg.sh (uses 7z + asar).
Fixed the Linux launcher to point at the right extracted directory (linux/run-codex.sh uses APP_DIR="$ROOT_DIR/app_asar"), and set ELECTRON_FORCE_IS_PACKAGED=1 + NODE_ENV=production so it behaves like a packaged app.
Rebuilt the two native Node modules that ship as macOS Mach-O binaries (better-sqlite3 + node-pty) into Linux .node ELF binaries and copied them into app_asar/node_modules/... via linux/scripts/build-native.sh.
Hit an Electron ABI mismatch (built against the wrong Electron/Node ABI), fixed by rebuilding with an Electron version that matches the runtime (on Arch I used system electron39): ELECTRON_VERSION=$(electron --version | tr -d v) linux/scripts/build-native.sh
Launched the app pointing it at the Linux Codex CLI binary: CODEX_CLI_PATH=/usr/bin/codex linux/run-codex.sh
Optional polish: added a .desktop launcher (linux/codex.desktop), and patched the main process bundle to auto-hide the menu bar on Linux (app_asar/.vite/build/main.js:552).