Beta:
codex-routeris still under active development.It works today, but the behavior is still being refined, especially around mirroring, edge cases, and overall UX. Expect rough edges, test carefully before depending on it, and keep a backup of
~/.codexif you are experimenting with it.
codex-router is a macOS-first wrapper around the stock codex CLI. It lets you keep multiple tagged Codex accounts with separate quotas while sharing one local Codex state across them.
In practice, it gives you:
- multiple tagged accounts such as
codex-1,codex-2 - a simple
switchcommand to choose which account pays for usage - a shared non-auth Codex environment across those accounts
- per-account status reporting with 5-hour and weekly remaining quota
If you use more than one Codex account, the stock CLI does not give you a simple way to swap accounts while keeping one local setup.
codex-router separates two concerns:
- auth is stored per tagged account
- non-auth local state is shared
That means you can switch accounts without manually rebuilding your local setup every time.
codex-router treats local Codex state in two buckets:
- auth state: stored per tag under
~/.codex-router/accounts/<tag>/auth.json - non-auth state: stored canonically under
~/.codex-router/shared
Current flow:
codex-router login -t <tag>logs in one tagged account.codex-router switch <tag>marks that tag as active.- routed
codexlaunches use that active tag's auth. - routed
codexlaunches use a thin runtime overlay over router-managed shared state.
The intended result is:
- account identity and quota come from the selected tag
- config, skills, MCP setup, sessions, and other non-auth state remain shared
codex-router status shows:
- how much 5-hour quota is left
- how much weekly quota is left
- the 5-hour reset window
- the weekly reset window
- which tag is active
- the account email when available
- whether the account is ready or needs login
Clone the repo, install dependencies, and build:
git clone <repo-url>
cd codex-router
npm install
npm run buildIf you want the local repo version available as codex-router in your shell:
npm link
hash -rYou can also run the built CLI directly without linking:
node dist/src/cli/index.js --helpRun this once to install the optional routed codex shim:
codex-router initThat installs:
~/.codex-router/bin/codex
Then add the printed path export to your shell profile so ~/.codex-router/bin comes before the real Codex binary on PATH.
If ~/.codex-router/shared is still empty and ~/.codex exists, init also imports your existing non-auth Codex state one time into router-managed shared storage. ~/.codex is read only during that bootstrap and is not modified afterward.
After that:
codex-routermanages account tags and status- routed
codexlaunches use the selected tag
codex-router login -t codex-1
codex-router login -t codex-2codex-router switch codex-1
codex-router switch codex-2codex-router currentcodex-router statuscodex-router status -t codex-1codex-router del -t codex-1Note:
- you cannot delete the currently active tag
- deleting a tag removes that tag's auth slot from
~/.codex-router/accounts/<tag>
This is the simplest way to explain and test how it works.
codex-router login -t codex-1
codex-router login -t codex-2codex-router switch codex-1
codexInside Codex:
- run
/status - confirm the account shown matches the
codex-1email - optionally change model using
/model - optionally note the session id
- exit Codex
codex-router switch codex-2
codexInside Codex:
- run
/status - confirm the account shown now matches the
codex-2email - verify your non-auth state is still there
Examples of non-auth state you may want to verify:
- model/config
- skills
- MCP setup
- sessions
If you want to prove session continuity explicitly:
codex resume <session-id>What this demonstrates:
- the billing/quota account changes when you
switch - local non-auth state is shared rather than isolated per account
codex-router status looks like this conceptually:
ACTIVE TAG 5H_LEFT WEEKLY_LEFT 5H_RESET WEEKLY_RESET ACCOUNT AUTH
* codex-1 98% 69% 4h 11m 6d 4h first@example.com ready
codex-2 100% 99% 5h 6d 5h second@example.com ready
Single-tag detail:
tag: codex-1
active: yes
five_hour_left_pct: 98%
weekly_left_pct: 69%
five_hour_reset_in: 4h 11m
weekly_reset_in: 6d 4h
raw_limit_source: app-server account/rateLimits/read
account: first@example.com
auth_state: ready
auth_storage_path: /Users/you/.codex-router/accounts/codex-1/auth.json
last_switch_at: 2026-04-02T...
last_status_check_at: 2026-04-02T...
When run in an interactive terminal, the table is themed with colors. When piped or when NO_COLOR is set, it falls back to plain text.
codex-router keeps non-auth state under ~/.codex-router/shared.
Current intended behavior:
initmay import existing non-auth state from~/.codexone time when router shared state is still empty- routed
codexlaunches useruntime/current-home/as a thin overlay with shared symlinks plus the active tag'sauth.json - runtime changes stay in router-managed shared state rather than syncing back into
~/.codex
This keeps account auth separate while keeping the local Codex environment shared across accounts.
codex-router keeps its own state under:
~/.codex-router
Important paths:
accounts/<tag>/auth.json— per-account auth slotshared/— canonical non-auth shared stateruntime/current-home/— assembled runtimeCODEX_HOMEused by routedcodexbin/codex— optional wrapper installed bycodex-router initstate/accounts.json— tag registry and last observed status snapshotsstate/wrapper.json— stored path to the real Codex binary
Before testing beta behavior, backing up ~/.codex is recommended:
rsync -a ~/.codex/ ~/.codex.backup/If you want a clean router reset:
rm -rf ~/.codex-routerThat removes router-managed tags and runtime state, but it does not delete ~/.codex.
After deleting ~/.codex-router, you will need to:
- log in your tagged accounts again
- run
codex-router initagain if you also want to recreate the wrapper setup
If you want to test the current behavior end-to-end:
codex-router statusshows5H_LEFTandWEEKLY_LEFTcodex-router statusshows both reset windows- colors appear in a real terminal
- output is plain when piped
Examples:
codex-router status
codex-router status | cat
codex-router status -t codex-1switch codex-1thencodexshows account 1 in/statusswitch codex-2thencodexshows account 2 in/status
- change model/config in routed
codex - exit Codex
- confirm
~/.codex/config.tomlreflects the change - relaunch routed
codexand verify the model did not reset
- add or change something in
~/.codex - run routed
codex - verify it is visible under router shared/runtime state
This usually means your linked executable is missing the execute bit or your shell resolved the wrong path.
Useful checks:
type -a codex-router
ls -l "$(command -v codex-router)"
hash -rRebuild and relink:
npm run build
npm link
hash -rRun directly from the repo:
node dist/src/cli/index.js statusOr link it:
npm linkMake sure ~/.codex-router/bin comes before the real Codex binary on PATH.
Check:
which codexThis means live limit data could not be extracted from the current Codex CLI/account state. The tool falls back to unknown instead of guessing.
Build:
npm run buildTypecheck:
npm run checkTest:
npm testDry-run package:
npm pack --dry-runThis project is still beta. In particular:
- runtime overlay and shared-state persistence semantics are still being refined
- edge cases around new top-level state created by Codex may still need work
- account-reuse and status metadata flows may still need more hardening
- UX and output formatting are still evolving
If you are testing it, treat it as an experimental power-user tool rather than a polished stable release.