Switch your login/profile/account for 10+ CLIs, including Codex and Claude Code.
1
stars
44
commits
Rust
primary language
Sep 9, 2026
updated
Work account, personal account, a client's account: most developer CLIs only hold one login at a time, so you end up signing out and back in all day. Switcheroo remembers each login in your OS credential store and puts the one you want back in a second, for Claude Code, Codex, Vercel, Wrangler, npm, Fly.io and more.
It does not create profiles or config directories. It swaps the CLI's live login, so every terminal, editor integration and script that uses that CLI follows along. For CLIs that report it (Claude Code, Codex, GitHub CLI) it also shows how much of each account's allowance is used and when it resets, so you know which account to switch to.
switcheroo save claude-code # remember the login you have now
switcheroo login claude-code # sign in as someone else, remember that too
switcheroo use claude-code work@acme.dev # switch; the previous login is remembered first
switcheroo tray # menu-bar quick switcher + web UI
macOS and Linux:
curl -fsSL https://raw.githubusercontent.com/ftchd/switcheroo/main/install.sh | sh
Windows (PowerShell):
irm https://raw.githubusercontent.com/ftchd/switcheroo/main/install.ps1 | iex
To build from source you need Rust and Node:
cd web && npm ci && npm run build && cd ..
cargo build --release # → target/release/switcheroo
Run switcheroo tray once; it detaches and keeps running in the background (switcheroo tray --stop ends it): a menu-bar item with one submenu per CLI, click an account to switch. switcheroo autostart enable (or the "Start at login" toggle) opens it when you sign in to the machine, and "Open Switcheroo…" gets you the full web UI for renaming, forgetting, settings and diagnostics.
No display needed: switcheroo serve runs the web UI on loopback, and an SSH tunnel (ssh -L 20123:127.0.0.1:20123 host, using the port it prints) puts it in your local browser.
Everything is a switcheroo subcommand with --json output, so it scripts well: switcheroo --help or the Reference page lists them all.
| CLI | Mechanism | What is touched |
|---|---|---|
| Claude Code | swap | keychain item Claude Code-credentials (macOS) or ~/.claude/.credentials.json, plus oauthAccount in ~/.claude.json; running sessions pick the change up |
| Codex CLI | swap | ~/.codex/auth.json (file credential mode); restart running sessions |
| GitHub CLI | native | gh auth switch --user; gh keeps the accounts itself |
| Vercel | swap | global auth.json token and currentTeam |
| Cloudflare Wrangler | swap | OAuth login default.toml |
| npm (also pnpm, yarn v1, bun) | swap | only the //registry.npmjs.org/:_authToken line of ~/.npmrc |
| Fly.io | swap | ~/.fly/config.yml, taking flyctl's lock first |
| Netlify | native | netlify switch --email; Netlify keeps the accounts itself |
| Gemini CLI, Turso, Expo / EAS, Railway | swap | experimental: formats verified from source, not yet on real logins |
Swap means Switcheroo captures the CLI's credential into your credential store and writes a remembered one back in its place. Native means the CLI already keeps several accounts and Switcheroo only runs its switch command; nothing is stored.
switcheroo providers prints this list with the exact files for your OS. Only CLIs found on PATH are managed; a tool installed inside a single project (for example wrangler in a repo's node_modules/.bin) is not visible until it is installed globally or its directory is on PATH. Doctor explains this next to the list of directories searched.
switcheroo update fetches the latest release for your platform, verifies it against the release's SHA256SUMS, replaces the binary in place and restarts the tray if it was running. switcheroo update --check only reports. The CLI, the web UI and the tray all point out a newer release until it is installed.
Before switching, Switcheroo warns about anything that would make it a no-op: environment variables the CLI prefers over its stored login (GH_TOKEN, CLOUDFLARE_API_TOKEN, VERCEL_TOKEN, ANTHROPIC_API_KEY, …), a CLI that caches credentials at startup, or an unsupported storage mode such as Codex's keyring option.
--vault file opts into a 0600 JSON file for machines without one. Switcheroo's own state.json holds emails, labels and timestamps, never tokens./usr/bin/security, the same tool Claude Code uses. Items created that way never trigger access prompts, and updating the binary does not break access.whoami commands.| Command | What it does |
|---|---|
switcheroo / status [--refresh] | Every detected CLI, who it is signed in as, remembered accounts |
save <provider> [--label NAME] | Remember the current login |
login <provider> [--label NAME] | Run the CLI's sign-in here, then remember the result |
use <provider> [account] | Switch; account by email, label or unique fragment, picker if omitted |
list [provider] · rename · remove | Manage remembered accounts |
usage [provider] [--refresh] | Used quota and reset times for signed-in accounts |
doctor · providers | Diagnostics and the provider catalog |
tray · serve [--bind] · open | Run the tray, the web server, or open the UI |
autostart enable|disable|status | Start the tray at login |
completions <shell> | Shell completions |
Global: --json, --vault auto|keychain|file, --data-dir DIR, -v, -q. Exit codes: 0 ok, 1 error, 2 usage, 3 CLI not installed, 4 nothing signed in.
cargo test # Rust unit tests, incl. a real keychain round trip on macOS
cd web && npm install && npm run dev # Vite on :5173, proxies /api to :7777
cargo run -- serve --dev --bind 127.0.0.1:7777 # dev server with a fixed session token
The architecture, invariants and the checklist for adding a provider are in CLAUDE.md. A provider is one file under src/providers/ built from a few slot adapters and an identity resolver, plus one line in the registry; the CLI, API, tray and web UI pick it up without changes.
44 commits
Rust
63.9%
TypeScript
33.0%
CSS
1.5%
Switch your login/profile/account for 10+ CLIs, including Codex and Claude Code.
1
stars
44
commits
Rust
primary language
Sep 9, 2026
updated
Work account, personal account, a client's account: most developer CLIs only hold one login at a time, so you end up signing out and back in all day. Switcheroo remembers each login in your OS credential store and puts the one you want back in a second, for Claude Code, Codex, Vercel, Wrangler, npm, Fly.io and more.
It does not create profiles or config directories. It swaps the CLI's live login, so every terminal, editor integration and script that uses that CLI follows along. For CLIs that report it (Claude Code, Codex, GitHub CLI) it also shows how much of each account's allowance is used and when it resets, so you know which account to switch to.
switcheroo save claude-code # remember the login you have now
switcheroo login claude-code # sign in as someone else, remember that too
switcheroo use claude-code work@acme.dev # switch; the previous login is remembered first
switcheroo tray # menu-bar quick switcher + web UI
macOS and Linux:
curl -fsSL https://raw.githubusercontent.com/ftchd/switcheroo/main/install.sh | sh
Windows (PowerShell):
irm https://raw.githubusercontent.com/ftchd/switcheroo/main/install.ps1 | iex
To build from source you need Rust and Node:
cd web && npm ci && npm run build && cd ..
cargo build --release # → target/release/switcheroo
Run switcheroo tray once; it detaches and keeps running in the background (switcheroo tray --stop ends it): a menu-bar item with one submenu per CLI, click an account to switch. switcheroo autostart enable (or the "Start at login" toggle) opens it when you sign in to the machine, and "Open Switcheroo…" gets you the full web UI for renaming, forgetting, settings and diagnostics.
No display needed: switcheroo serve runs the web UI on loopback, and an SSH tunnel (ssh -L 20123:127.0.0.1:20123 host, using the port it prints) puts it in your local browser.
Everything is a switcheroo subcommand with --json output, so it scripts well: switcheroo --help or the Reference page lists them all.
| CLI | Mechanism | What is touched |
|---|---|---|
| Claude Code | swap | keychain item Claude Code-credentials (macOS) or ~/.claude/.credentials.json, plus oauthAccount in ~/.claude.json; running sessions pick the change up |
| Codex CLI | swap | ~/.codex/auth.json (file credential mode); restart running sessions |
| GitHub CLI | native | gh auth switch --user; gh keeps the accounts itself |
| Vercel | swap | global auth.json token and currentTeam |
| Cloudflare Wrangler | swap | OAuth login default.toml |
| npm (also pnpm, yarn v1, bun) | swap | only the //registry.npmjs.org/:_authToken line of ~/.npmrc |
| Fly.io | swap | ~/.fly/config.yml, taking flyctl's lock first |
| Netlify | native | netlify switch --email; Netlify keeps the accounts itself |
| Gemini CLI, Turso, Expo / EAS, Railway | swap | experimental: formats verified from source, not yet on real logins |
Swap means Switcheroo captures the CLI's credential into your credential store and writes a remembered one back in its place. Native means the CLI already keeps several accounts and Switcheroo only runs its switch command; nothing is stored.
switcheroo providers prints this list with the exact files for your OS. Only CLIs found on PATH are managed; a tool installed inside a single project (for example wrangler in a repo's node_modules/.bin) is not visible until it is installed globally or its directory is on PATH. Doctor explains this next to the list of directories searched.
switcheroo update fetches the latest release for your platform, verifies it against the release's SHA256SUMS, replaces the binary in place and restarts the tray if it was running. switcheroo update --check only reports. The CLI, the web UI and the tray all point out a newer release until it is installed.
Before switching, Switcheroo warns about anything that would make it a no-op: environment variables the CLI prefers over its stored login (GH_TOKEN, CLOUDFLARE_API_TOKEN, VERCEL_TOKEN, ANTHROPIC_API_KEY, …), a CLI that caches credentials at startup, or an unsupported storage mode such as Codex's keyring option.
--vault file opts into a 0600 JSON file for machines without one. Switcheroo's own state.json holds emails, labels and timestamps, never tokens./usr/bin/security, the same tool Claude Code uses. Items created that way never trigger access prompts, and updating the binary does not break access.whoami commands.| Command | What it does |
|---|---|
switcheroo / status [--refresh] | Every detected CLI, who it is signed in as, remembered accounts |
save <provider> [--label NAME] | Remember the current login |
login <provider> [--label NAME] | Run the CLI's sign-in here, then remember the result |
use <provider> [account] | Switch; account by email, label or unique fragment, picker if omitted |
list [provider] · rename · remove | Manage remembered accounts |
usage [provider] [--refresh] | Used quota and reset times for signed-in accounts |
doctor · providers | Diagnostics and the provider catalog |
tray · serve [--bind] · open | Run the tray, the web server, or open the UI |
autostart enable|disable|status | Start the tray at login |
completions <shell> | Shell completions |
Global: --json, --vault auto|keychain|file, --data-dir DIR, -v, -q. Exit codes: 0 ok, 1 error, 2 usage, 3 CLI not installed, 4 nothing signed in.
cargo test # Rust unit tests, incl. a real keychain round trip on macOS
cd web && npm install && npm run dev # Vite on :5173, proxies /api to :7777
cargo run -- serve --dev --bind 127.0.0.1:7777 # dev server with a fixed session token
The architecture, invariants and the checklist for adding a provider are in CLAUDE.md. A provider is one file under src/providers/ built from a few slot adapters and an identity resolver, plus one line in the registry; the CLI, API, tray and web UI pick it up without changes.
44 commits
Rust
63.9%
TypeScript
33.0%
CSS
1.5%