claude-switch
Health Pass
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 11 GitHub stars
Code Pass
- Code scan — Scanned 6 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Swap between Claude accounts (Code + Desktop) on macOS with a single command. Fully offline. Zero storage.
claude-switch
Swap between Claude accounts (Code + Desktop) on macOS with a single command.
Fully offline. Zero storage. No tokens are sent anywhere and nothing is written to disk by csw. All credentials live exclusively in macOS Keychain — the same encrypted, hardware-backed store that Claude itself uses. No config files, no dotfiles, no plaintext secrets.
Install
Option 1 — download binary (recommended)
curl -fsSL https://raw.githubusercontent.com/mtxr/claude-switch/main/install.sh | bash
This downloads the latest release binary for your architecture (arm64 or x86_64) to ~/.local/bin/csw.
Option 2 — build from source
Requires Zig 0.16.0 (or install via mise: mise use [email protected]).
git clone https://github.com/mtxr/claude-switch
cd claude-switch
zig build -Doptimize=ReleaseSmall
# binary at: zig-out/bin/csw
cp zig-out/bin/csw ~/.local/bin/csw
Option 3 — manual download
Grab the binary for your architecture from Releases, put it somewhere in your $PATH, and chmod +x it.
Make sure ~/.local/bin is in your $PATH (add to ~/.zshrc if needed):
export PATH="$HOME/.local/bin:$PATH"
You also need sk or fzf for the interactive picker:
brew install sk
Migrating from the Python version
If you were using the previous Python-based csw, your profiles and keychain entries are fully compatible — no data migration needed. The Rust binary reads the exact same Keychain entries and file paths.
The only thing that changes is how csw is installed:
1. Remove the old wrapper
rm ~/.local/bin/csw ~/.local/bin/claude-switch
2. Install the new binary
curl -fsSL https://raw.githubusercontent.com/mtxr/claude-switch/main/install.sh | bash
3. Verify everything still works
csw whoami
csw list
Your profiles should appear exactly as before. Nothing to re-save.
Note:
csw updatenow self-updates by downloading the latest binary from GitHub Releases instead of runninggit pull. If you cloned the repo just for the Python version, you can delete it.
Getting started
You need to save each account as a profile before you can switch between them. Do this once per account:
1. Save your current account (e.g. work)
csw save work
This saves the session tokens into macOS Keychain and migrates ~/.claude.json and ~/.claude/ to profile-specific paths (~/.claude.work.json, ~/.claude.work/), leaving symlinks in place. From now on, switching just swaps the symlinks.
2. Create a slot for the second account and log in
csw new personal # creates ~/.claude.personal.json + ~/.claude.personal/, activates symlinks
claude auth login # logs in as the personal account into the active slot
3. Save the second account
csw save personal
You're set. Switch between accounts instantly:
csw use work
csw use personal
# or interactively:
csw pick
Usage
csw save <name> Save current sessions (Code + Desktop) as a named profile
csw use <name> Switch to a saved profile
csw new <name> Create a new empty profile slot (then: claude auth login)
csw delete <name> Delete a profile and its data
csw list List all saved profiles
csw whoami Show active session info (Code + Desktop + saved profiles)
csw pick Interactive fuzzy picker (sk / fzf)
csw update Update csw to the latest release
csw logout-all Log out of all accounts and remove active symlinks
How it works
Security model
csw does not create any files or directories of its own. All session tokens are stored in macOS Keychain, protected by the same OS-level encryption and access controls that guard your passwords, SSH keys, and certificates.
| Data | Where it lives |
|---|---|
| Claude Code tokens | Keychain: csw-code-<profile> |
| Active Code session | Keychain: Claude Code-credentials (managed by Claude) |
| Active Desktop session | Electron SQLite cookie, AES-128-CBC encrypted (managed by Claude Desktop) |
| Desktop encryption key | Keychain: Claude Safe Storage (managed by Claude Desktop) |
| Profile configs | ~/.claude.<profile>.json + ~/.claude.<profile>/ |
| Active profile | ~/.claude.json → symlink, ~/.claude/ → symlink |
- No network requests are ever made.
- No plaintext tokens ever touch the filesystem.
- Both Claude Code and Claude Desktop are optional — csw works with either or both.
- On switch, Claude Desktop is quit automatically and relaunched.
Profile switching
Switching profiles is instant because ~/.claude.json and ~/.claude/ are symlinks. Changing them is an atomic filesystem operation — no copying, no rewriting.
Claude Desktop uses real directory renames instead of symlinks (Electron doesn't follow symlinks for its data directory). On switch, csw renames Claude/ → Claude.<from>/ and Claude.<to>/ → Claude/.
Development
git clone https://github.com/mtxr/claude-switch
cd claude-switch
# Debug build (fast compile, leak detection)
zig build
# Optimised builds
zig build -Doptimize=ReleaseSafe # bounds checks on, ~670 KB
zig build -Doptimize=ReleaseSmall # smallest binary
zig build -Doptimize=ReleaseFast # max speed
# Run tests
zig build test
CI runs on every push: zig build (debug) and zig build test.
Releases are built automatically when a tag is pushed:
git tag v0.2.0
git push origin --tags
GitHub Actions cross-compiles arm64 and x86_64 binaries (-Doptimize=ReleaseSmall) and publishes them to the release.
License
MIT — see LICENSE.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found