中文 | English
OpenCodex is a lightweight implementation of a Codex runtime environment. It runs the official Codex Renderer in a standard Web environment, allowing users to remotely access and operate Codex running on a target machine from any device and network.
In one line:
browser -> web-shell -> official Codex renderer -> bridge polyfill -> gateway -> Codex app-server / local host capabilities
Bad timing: just as this project was about to be open sourced, ChatGPT App added Codex support.
OpenCodex still has several advantages compared with the official mobile path:
- No proxy setup required.
- No Google Play account required.
- Full Codex feature support, including file tree, terminal, review, and other workflows that make AI coding practical anytime and anywhere.
This software is currently a beta version and may still have issues. If you find a problem, please report it through an issue so the developer can fix it.
The project has three main parts:
| Module | Purpose |
|---|---|
web-shell/ |
Browser entry point for loading the official renderer and providing the renderer runtime environment. |
gateway/ |
Local Node gateway that provides HTTP, WebSocket, IPC compatibility, local files, git, terminal, state sync, and app-server forwarding. |
/electron-to-web/ |
Electron semantics adapter. The gateway prefers it by default to reuse Electron IPC behavior, with a self-implemented DirectGatewayElectronIpcPort as an alternative. |
This software does not modify Codex code. It only uses the corresponding Renderer artifacts.
When the Gateway starts, it automatically checks whether the local Codex installation has been updated. If an update is found, it automatically refreshes the Renderer artifacts used by OpenCodex, which means it follows the corresponding Codex version.
flowchart TB
L1["Access Layer<br/>Remote device browser<br/>Starts access and displays the interactive UI"]
L2["Web Host Layer<br/>web-shell<br/>Hosts the official Renderer in a standard Web environment"]
L3["Renderer Compatibility Layer<br/>codex-bridge-polyfill<br/>Fills Electron Renderer runtime dependencies<br/>and converts Renderer calls into Web IPC"]
L4["Gateway Layer<br/>gateway<br/>Handles auth, HTTP / WebSocket, IPC dispatch<br/>and acts as the unified target-machine entry point"]
L5["Host Capability Adapter Layer<br/>Gateway IPC / electron-to-web / Direct IPC<br/>Adapts Desktop host semantics, local state, files, terminal, Git, and related capabilities"]
L6["Codex Business Capability Layer<br/>Codex app-server<br/>Provides sessions, models, config, MCP, task execution, and other core capabilities"]
L7["Official Artifact Layer<br/>Codex Desktop / Renderer Bundle<br/>Provides the official Renderer artifact and version source"]
L1 --> L2
L2 --> L3
L3 --> L4
L4 --> L5
L5 --> L6
L7 -.provides Renderer artifact.-> L2
Core principles:
- Reuse the official Renderer instead of rewriting the main UI.
- Keep browser-side code focused on host-environment compatibility.
- Let the gateway own local capabilities and app-server proxying, so remote browsers do not directly access local tokens or the app-server.
- Record uncovered Desktop IPC calls in
reports/unknown-ipc.jsonland bridge them incrementally.
- Node.js 20 or newer
- pnpm
- Codex Desktop installed locally, recommended, or explicit environment variables pointing to the Codex Desktop app or official bundle.
- macOS / Windows. macOS is fully supported; Windows has not been tested yet.
Install dependencies:
pnpm installBuild first:
pnpm run build:vendorpnpm run build:gatewayStart the service:
Setting an access password is strongly recommended. You can copy the example config and edit the password:
cp config.example.yaml config.yamlYou can also create config.yaml manually in the current working directory:
auth:
password: "your-password"On the first startup, the gateway rewrites this field to sha256-v1:<hash> so the plaintext password is not kept in the config file. If config.yaml is missing, auth.password is missing, or the field is empty, password authentication stays disabled.
Only the block-style YAML form shown above is supported; inline forms such as auth: { password: "..." } are rejected.
HOST=0.0.0.0 PORT=3737 pnpm run web:devHealth check:
curl http://127.0.0.1:3737/api/health
Remote access:
Use Tailscale, ZeroTier, a company VPN, or a similar private network solution for secure remote LAN access. Direct public exposure is not recommended.
| Variable | Default | Description |
|---|---|---|
HOST |
0.0.0.0 |
Gateway bind address. The default is intended for remote access. |
PORT |
3737 |
Gateway port. |
CODEX_WEB_AUTH_TOKEN_TTL_MS |
43200000 |
Gateway access token lifetime. The default is 12 hours. |
CODEX_WEB_DEBUG |
empty | Set to 1 or true for verbose debug logs. |
CODEX_WEB_SLOW_LOG_MS |
750 |
IPC slow-call logging threshold. |
CODEX_WEB_LOCAL_FILE_TOKEN_TTL_MS |
300000 |
Lifetime for local file preview URL tokens. |
CODEX_DESKTOP_APP_PATH |
auto scan | Explicit path to the Codex Desktop app or its app.asar. |
CODEX_WEB_OFFICIAL_BUNDLE_DIR |
cache/official-bundle |
Cache directory for extracted official webview assets. |
CODEX_WEB_IPC_IMPL |
electron-to-web |
Set to direct to use the direct IPC fallback implementation. |
| Path | Description |
|---|---|
gateway/src/server.ts |
Gateway entry point. It wires HTTP, WebSocket, auth, official bundle loading, IPC, and app-server integration. |
gateway/src/codex-app-server.ts |
Codex app-server client for connection management, request forwarding, startup cache warmup, and health status. |
gateway/src/ipc/ |
Gateway IPC abstractions and Electron/Codex compatibility implementations. |
gateway/src/official/ |
Codex Desktop app.asar scanning, identification, caching, and webview extraction. |
web-shell/index.html |
Browser bootstrap shell for login, settings, and loading the patched official renderer. |
web-shell/codex-bridge-polyfill.js |
Browser-side Electron/Codex bridge polyfill. |
reports/unknown-ipc.jsonl |
Runtime log for unknown IPC calls. |
| Script | Description |
|---|---|
pnpm run build:gateway |
Compile gateway/src into gateway/dist. |
pnpm run web:dev |
Start the compiled gateway. |
pnpm run build:vendor |
Build vendor/electron-to-web. |
pnpm run test:vendor |
Run vendor/electron-to-web tests. |
The first load can be slow and is affected by remote LAN bandwidth. If the history is not visible at first, wait for a while and it should appear.
Check whether the gateway is listening:
curl http://127.0.0.1:3737/api/healthIf the port is already in use, start on another port:
PORT=3738 pnpm run web:devSet the Codex Desktop path explicitly:
CODEX_DESKTOP_APP_PATH="/Applications/Codex.app" pnpm run web:devYou can also choose the bundle cache directory:
CODEX_WEB_OFFICIAL_BUNDLE_DIR="./cache/official-bundle" pnpm run web:devInspect unknown IPC logs and report them to the developer:
tail -f reports/unknown-ipc.jsonl


