The Problem
Developers using the Codex desktop client must switch between many external LLM providers (Anthropic, Kimi, DeepSeek, etc.). Each provider requires its own credential handling, service installation, and UI integration, leading to duplicated configuration, potential credential leakage, and a fragmented user experience.
What This Does
codex-router installs a single background service that acts as a credential‑isolated gateway for all supported providers. The router speaks the Codex Responses API, merges external models into Codex’s native catalog, and exposes a unified endpoint for the Gemini CLI and DeepSeek Harness.
Key files:
apps/desktop/src-tauri/src/main.rs– Rust entry point that launches the Tauri service.apps/desktop/ui/app.js– Front‑end bootstrap that registers the router UI.src/router.mjs– Core request dispatcher (35 outgoing imports, highest instability).src/paths.mjsandsrc/file-security.mjs– Central path resolution and security checks; 75 and 39 modules depend on them respectively.
How It Is Wired
- Startup – The OS launches the Tauri binary (
main.rs). It readsapps/desktop/src-tauri/tauri.conf.jsonand spawns the Node environment defined inapps/desktop/package.json. - UI → Service –
ui/app.jsloadssrc/router.mjswhich registers HTTP routes on the local gateway. Incoming calls from the Codex client hitsrc/router.mjs, which forwards them to provider‑specific adapters located undersrc/provider‑selection. - Path & Security – Every request first passes through
src/paths.mjs(path resolution) andsrc/file-security.mjs(credential sandboxing). Their high inbound fan‑in makes them the primary blast‑radius; changes here affect all 114 dependent modules. - Provider Selection –
src/provider-selection.mjsconsultssrc/model-registry.mjs(26 inbound, 2 outbound) to map a logical model name to a concrete provider config (JSON files underconfig/*). - Command Execution – Heavy decision logic lives in
src/caller-auth.mjs(30 inbound, 0 outbound) andsrc/spawnable-command.mjs; both exhibit high branching density (≈28 branches/93 lines). They ultimately invoke the CLI wrappers inbin/(e.g.,bin/model-router,bin/doctor). - Response – The router returns a Codex‑compatible JSON payload, which the desktop UI injects into the model picker.
No circular imports were detected; the most unstable modules (src/router.mjs, src/doctor.mjs) have only outgoing edges, limiting hidden side‑effects.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/codex-router
cd codex-router
# Install the desktop app (macOS/Linux)
npm ci # installs Node deps from apps/desktop/package.json
cargo build --release # builds the Tauri binary (src-tauri)
# Guided setup – registers providers and installs the per‑user service
./bin/model-router setup --guided
Configuration files live under config/. For example, config/kimi/kimi.json holds Kimi OAuth settings, while config/anthropic/anthropic.json stores Anthropic keys. The installer reads any existing credentials and prompts only for missing ones via a hidden terminal prompt.
Running the router manually:
./bin/model-router start # starts the local gateway
The Codex client will automatically discover the gateway on http://127.0.0.1:<port>.
Real‑World Use
A software team wants to evaluate DeepSeek and Grok alongside OpenAI without exposing API keys to the main CI runner. They install codex-router on a developer workstation, run codex-router setup --guided, and add the generated config/deepseek/deepseek.json to their version‑controlled, encrypted secrets store. All CI jobs now reference the local gateway, keeping keys off the build server while still allowing automated tests to hit the external models.
Code Health & Issues
- Measured Findings (125 total)
- High‑clarity hub –
src/paths.mjs,src/file-security.mjs,src/caller-auth.mjseach have >30 dependents; keep them small and stable. - Medium cognitive load – 40 files show >28 branch points in ≤93 lines (e.g.,
src/caller-auth.mjs). Refactor into strategy tables. - Oversized files –
src/vision-bridge.mjs,apps/desktop/ui/i18n.mjs,src/catalog.mjsexceed 800 lines; split by responsibility. - Duplicated code – 543 identical 6‑line blocks across 127 files (e.g.,
Formula/codex-router.rb,apps/desktop/ui/app.js). Extract shared helpers.
- Code‑Health Audit
- MEDIUM –
.github/workflows/ci.ymllackspersist-credentials: falseon the checkout step. Add the flag to prevent token leakage. - LOW – No
timeout-minuteson CI jobs; set a realistic timeout to avoid overlapping runs.
- Repository Hygiene – Tests (
test/), CI (GitHub Actions), license, and lockfiles are present; no Dockerfile or committed secrets detected.
The Bottom Line
codex-router delivers a functional, single‑point integration layer for many LLM providers, with a clear installation path and solid test coverage. The core routing logic is centralized in a few high‑impact modules, so careful changes are required there. Code size and duplication issues should be addressed before scaling the project, but the repo is otherwise healthy and ready for production use by teams needing credential‑safe multi‑provider access.