npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

codex-multi

v0.3.2

Published

Run multiple Codex accounts with isolated logins, memorable aliases, and one shared skills setup.

Readme

codex-multi

Multiple Codex accounts. One command. One shared skills setup.

codex-personal · codex-work · codex-client

Codex Multi gives every Codex account its own launcher and isolated login while keeping your existing config, skills, plugins, rules, MCP servers, memories, and sessions shared.

$ npx codex-multi add --name Personal --slug personal
Sign in to the Codex account for "Personal".
...
Added Personal. Launch it with: codex-personal

$ npx codex-multi add --name Work --slug work
$ codex-personal
$ codex-work exec "review this repository"

Profiles do not overwrite ~/.codex/auth.json. Each launcher sets a different CODEX_HOME, so two accounts can run concurrently without a global “active account” race.

Different profiles run concurrently. A single profile is lifecycle-locked while its Codex process is active so login, rename, or removal cannot replace credentials underneath that process.

On macOS, profiles can also run side by side in the Codex desktop app (the ChatGPT desktop app with Codex built in): cpm add --desktop installs a Spotlight-findable alias app per profile — its own name, its own color-badged icon, its own sign-in — while chats and shared Codex state keep working exactly as above. See Desktop app aliases (macOS).

Install skills once, use them everywhere

Your Codex skills stay in the normal ~/.codex/skills directory. Codex Multi links that same directory into every managed profile, so a skill installed once is immediately available from codex-personal, codex-work, and every other account alias.

The same sharing model covers rules, plugins, MCP configuration, memories, and sessions. Only credentials, generated profile config, and process-local runtime files stay isolated. You get separate accounts without maintaining separate toolboxes.

Install

Requires Node.js 18+ and the official codex CLI on PATH.

npx

npx codex-multi add

There is no install step. After login, launch the generated alias directly:

codex-personal

Launchers created from an npx run pin the manager version that created them, so they keep working after npm clears its temporary cache without silently adopting future code. Run npx --yes --package=codex-multi@latest codex-multi sync to upgrade them to the latest release.

Global install

For faster launcher startup and offline use:

npm install -g codex-multi
cpm add

Both cpm and codex-multi invoke the manager after a global install. Account launchers always use the codex-<slug> form.

From source

git clone https://github.com/nhocconan/codex-multi.git
cd codex-multi
npm install
npm run verify
npm install -g .

Launchers are installed into a writable directory on PATH, preferring ~/.local/bin. If that directory is not on PATH, the tool prints the exact line to add to your shell profile.

Quick start

# Browser login
cpm add --name Personal --slug personal

# Device-code login for a remote/headless terminal
cpm add --name Work --slug work --device-auth

# Import the login already stored in ~/.codex/auth.json
cpm import --name Current --slug current

# Create a profile that also gets a macOS desktop app alias
cpm add --name Work --slug work --desktop

# See all launchers
cpm list

# Use an account anywhere normal codex works
codex-personal
codex-work exec "fix the failing tests"
codex-work review
codex-personal resume --last

Running cpm with no arguments opens an interactive profile picker. Choose Manage profiles to sign in with another account, edit a profile, or remove one you no longer use. Removal asks for confirmation and deletes that profile's isolated login and owned launcher. It leaves other profiles and the base ~/.codex/auth.json alone.

To sign in again with the same profile, run:

codex-student login --device-auth

# With npx, including when an older launcher still blocks login:
npx --yes --package=codex-multi@latest codex-multi login student --device-auth

Omit --device-auth for browser login. You can also use cpm login student or choose Manage profiles → Student → Sign in with another account. When a launch detects missing or unusable local credentials in an interactive terminal, it offers device-code or browser login and continues the original command after sign-in. Noninteractive launches print recovery commands instead of prompting. Credentials that remain on disk but have been revoked by the server may still need an explicit login command.

The slug and launcher stay the same. If the new login fails, Codex Multi restores the previous profile login. If you have already removed a profile, cpm add --name Student --slug student can reuse its slug.

Commands

| Command | Purpose | |---|---| | cpm | Interactive picker | | cpm add | Create a profile and run codex login | | cpm import | Copy the current file-based Codex login into a profile | | cpm list | Show profiles and safe login metadata | | cpm launch <slug> | Launch a profile and pass all remaining args to Codex | | cpm use <slug> | Alias for launch | | cpm desktop <slug> | Open a profile in an isolated Codex desktop app instance (macOS) | | cpm login <slug> | Replace a login; restores the old one if login fails | | cpm edit <slug> | Change the label or codex-<slug> command; --desktop/--no-desktop/--desktop-name/--desktop-color | | cpm remove <slug> | Delete one profile, its isolated credentials, and its desktop alias | | cpm sync | Rebuild profile config, launcher scripts, and desktop aliases | | cpm doctor | Audit auth, isolation, duplicate credentials, launchers, and aliases |

Common options:

--name, -n <label>
--slug, -s <suffix>
--device-auth
--api-key-env <ENV_NAME>
--access-token-env <ENV_NAME>
--desktop                 also install a desktop app alias (macOS)
--desktop-name <name>     custom alias name, e.g. "Codex Job"
--desktop-color <color>   alias icon badge color (auto|none|red|orange|…)
--separated               keep this profile's Codex state fully private

Secrets are deliberately accepted through environment variable names instead of literal flags, keeping them out of shell history and process listings:

export MY_CODEX_API_KEY="..."
cpm add --name API --slug api --api-key-env MY_CODEX_API_KEY
unset MY_CODEX_API_KEY

How it works

OpenAI documents that Codex stores file-based credentials in $CODEX_HOME/auth.json and that CODEX_HOME defaults to ~/.codex. Codex Multi uses that supported boundary:

~/.config/codex-multi/
├── profiles.json
├── profiles/
│   ├── personal/
│   │   ├── auth.json       real file: Personal credentials
│   │   ├── config.toml     regenerated config, credential store forced to file
│   │   ├── skills -> ~/.codex/skills
│   │   ├── sessions -> ~/.codex/sessions
│   │   └── ...             other non-auth state shared from ~/.codex
│   └── work/
│       ├── auth.json       real file: Work credentials
│       └── ...
└── desktop/
    └── work/               per-profile desktop app data (macOS aliases)

~/.local/bin/
├── codex-personal
└── codex-work

On every launch the manager:

  1. verifies the profile has usable credentials;
  2. refreshes links to the base Codex home;
  3. regenerates config.toml from the current base config and forces cli_auth_credentials_store = "file";
  4. removes competing auth environment variables;
  5. starts the current codex binary with the profile’s CODEX_HOME;
  6. relays signals and returns Codex’s exit code.

Codex can refresh its tokens normally because each profile’s auth.json is a real writable file. Process-local directories such as ipc, process_manager, and temporary files also stay private to each profile. The registry contains labels and slugs only—never tokens.

See OpenAI’s Codex authentication documentation for the credential-storage contract and security guidance.

Desktop app aliases (macOS)

Profiles can also open in the official Codex desktop app (the ChatGPT desktop app with Codex built in, or a standalone Codex.app) side by side, each signed into its own account:

# While creating a profile
cpm add --name Work --slug work --desktop

# Or later / from the interactive "Manage profiles" menu
cpm edit work --desktop
cpm edit work --desktop-name "Codex Job"
cpm edit work --no-desktop

# Straight from the terminal
cpm desktop work

Enable desktop for an existing profile

On macOS, install the official Codex desktop app first. You can reuse a profile already registered with Codex Multi; adding its desktop alias keeps its existing credentials and does not require creating the profile again.

# Get the latest manager and refresh existing launchers/aliases
npx --yes --package=codex-multi@latest codex-multi sync

# Find the existing profile's slug (the suffix in codex-<slug>)
npx --yes --package=codex-multi@latest codex-multi list

# Replace work with your existing slug; optionally choose a name and color
npx --yes --package=codex-multi@latest codex-multi edit work --desktop \
  --desktop-name "Codex Work" --desktop-color blue

# Open it immediately, then check the installation
npx --yes --package=codex-multi@latest codex-multi desktop work
npx --yes --package=codex-multi@latest codex-multi doctor

Find Codex Work in Spotlight or ~/Applications for subsequent launches. With a global install, the equivalent enable command is cpm edit work --desktop. Run the enable command once for each existing profile you want in the desktop app; use a different alias name for each. To remove only the alias, run cpm edit work --no-desktop (or the same npx invocation with edit work --no-desktop); the profile and its credentials remain available.

If detection fails, set CODEX_MULTI_DESKTOP_APP to the installed .app path when running the enable command. If a CLI session holds the profile lock, exit that session before enabling or refreshing its alias. After a manager update, run the latest sync command above on each machine to refresh its launchers.

Each profile gets an alias app in ~/Applications, named after the detected desktop app plus the profile label (e.g. ChatGPT Work, ChatGPT Teacher). Spotlight or Raycast finds it, and you can pin it to the Dock. Every alias icon is the app's own icon with a color badge in the corner, so profiles are distinguishable at a glance; the color is assigned per profile (stable, derived from the slug) and can be chosen explicitly:

cpm edit work --desktop-color blue     # red orange yellow green teal blue
                                         # purple pink cyan lime — or none
cpm edit work --desktop-color auto     # back to the per-slug default

Under the hood each alias launches the unmodified desktop app with the profile's CODEX_HOME and its own app data directory, so sign-in sessions, window state, and credentials stay per profile while Codex history, projects, skills, and config remain shared from ~/.codex — chats themselves are cloud-synced per account. The desktop app's UI-state file stays private per profile so simultaneous instances never conflict. Opening the same alias twice reuses the running instance.

Aliases use a private, fully bundled manager runtime under ~/.config/codex-multi/runtime, so they continue working if an npx cache is removed. They use the Node executable available when installed; run cpm sync after moving or removing that Node installation. Each alias refreshes the profile's shared config before launching and clears ambient auth variables. Quit a profile's desktop instance before signing in again, renaming its command suffix, or removing it. Alias names and colors can be refreshed while it runs.

If a desktop launch times out, credential changes, renames, and removal stay blocked until the app is observed running or you cancel the launch. After quitting the app and cancelling any queued launch, recover with:

cpm desktop-reset-pending work --confirm-quit

This command refuses to clear the pending launch while that profile is running.

Aliases carry an ownership marker in their bundle Info.plist; cpm only ever touches its own bundles and never replaces a foreign app of the same name. An alias owned by another profile or manager data root is also a conflict. cpm remove deletes the alias and its desktop app data; cpm sync and cpm doctor keep aliases consistent with the registry.

One macOS limit to know: while profile instances are running, their windows use the official app's Dock/⌘-Tab icon. macOS exposes a running app's icon as read-only to other processes; the official app would need to support changing its own icon for each profile. This manager cannot set it through supported external APIs. The distinct icons and names apply where you pick the profile: Spotlight, Raycast, Launchpad, and pinned Dock aliases. The larger color badges distinguish these aliases; they do not change the official app's running Dock icons. Connector OAuth callbacks using the codex: scheme can still reach the default app instance; this tool does not register a callback chooser by default. Enable the optional router below to choose which running profile receives browser approvals.

Apps, plugins, and browser approvals

Shared profiles reuse the base Codex skills, plugins, and MCP configuration. A new --separated profile keeps those files private, while its managed config.toml still mirrors the base configuration. Custom MCP servers that use credentials from your shell environment keep their own authentication behavior; Codex Multi isolates Codex login credentials, not every third-party environment variable.

Enable callback routing once on macOS before connecting apps in separate profiles:

npx --yes --package=codex-multi@latest codex-multi callback-router enable
npx --yes --package=codex-multi@latest codex-multi callback-router status

This installs a small local helper and a user LaunchAgent. It registers the codex: URL handler and keeps that registration active while enabled, because the official app may reclaim it when starting. The official app remains unchanged. The helper compiles locally using Apple Command Line Tools; if they are missing, run xcode-select --install and retry. macOS may ask for Automation permission to send the approval to Codex.

For Gmail, Google Drive, GitHub, Figma, or another browser-based connector:

  1. Open the intended profile and start its connection in the official app.
  2. Check the browser is signed into the service account you want, then approve.
  3. In Choose the Codex profile for this callback, explicitly select that same running profile and continue. There is no default selection.
  4. Confirm the connection appears in that profile. Repeat independently for another account or a separated profile.

Only running apps are offered. If an app closes before delivery, the router reports failure; it never sends the approval to another account. Approval URLs stay in memory and are never written to disk or passed to subprocesses.

To stop routing and restore the previous URL handler:

npx --yes --package=codex-multi@latest codex-multi callback-router disable

With routing off, callbacks use the default official app instance and may reach a different profile. Existing connections remain managed by the official app. Each connector still requires its own service approval and account validation.

If you want a profile whose Codex state is not shared at all (private history, projects, and sessions), create it with --separated:

cpm add --name Lab --slug lab --separated

Importing the current account

cpm import reads ~/.codex/auth.json. If Codex is configured to keep credentials only in the OS keyring, there may be no file to import. Create a file-based login first:

codex -c 'cli_auth_credentials_store="file"' login
cpm import --name Current --slug current

Treat every managed auth.json like a password. They are written with mode 0600 on Unix and must never be committed, pasted into issues, or shared.

Environment overrides

These are useful for testing or nonstandard installations:

| Variable | Meaning | |---|---| | CODEX_MULTI_HOME | Manager state root | | CODEX_MULTI_BASE_HOME | Shared base Codex home (default ~/.codex) | | CODEX_MULTI_BIN_DIR | Launcher directory | | CODEX_MULTI_CODEX_BIN | Exact Codex executable | | CODEX_MULTI_DESKTOP_APP | Path to the desktop .app bundle | | CODEX_MULTI_APPS_DIR | Directory for desktop aliases (default ~/Applications) |

Design boundaries

  • This tool manages Codex accounts for the CLI and launches the official desktop app with per-profile data. It never modifies the desktop app itself and never copies credentials into the base ~/.codex/auth.json.
  • Codex configuration profiles selected by codex --profile customize model and sandbox settings; they are separate from the account profiles managed here.
  • Non-auth Codex state is intentionally shared across profiles. Use cpm add --separated when a profile needs fully isolated histories and plugins.
  • Launchers and desktop aliases never replace unrelated existing files. cpm doctor reports the collision.

Development

npm install
npm run typecheck
npm test
npm run build
npm pack --dry-run

The published CLI keeps its runtime surface small: cross-spawn safely runs Codex’s Windows .cmd shim, proper-lockfile protects profile lifecycle operations across processes and recovers stale locks after crashes, and the dependency-free pngjs recolors alias icons without native image libraries.

License

MIT