Run two Claude Code accounts (personal and work) on the same machine, side by side, without logging out each time.
How it works
Claude Code stores everything that makes an account "yours" — auth tokens, settings, history, projects, plugins, agents, hooks — inside a single config directory (default ~/.claude).
Setting the CLAUDE_CONFIG_DIR environment variable points Claude at a different directory. Each directory is a fully isolated profile.
Setup
Add these aliases inside the if status is-interactive block in ~/.config/fish/config.fish:
alias claude-personal "CLAUDE_CONFIG_DIR=$HOME/.claude-personal claude" alias claude-work "CLAUDE_CONFIG_DIR=$HOME/.claude-work claude"
Reload:
source ~/.config/fish/config.fish
Then run each alias once. Claude Code creates the config directory on first launch and prompts you to log in with the matching account.
claude-personal # log in with personal account claude-work # log in with work account
Both accounts stay logged in across reboots until you /logout.
Migrating existing history into a profile
Each profile starts empty, so --resume and the up-arrow prompt history won't show anything you did before the split. If you want your existing ~/.claude/ history available in (say) the personal profile, copy it over once:
mkdir -p ~/.claude-personal cp -R ~/.claude/projects ~/.claude-personal/ cp ~/.claude/history.jsonl ~/.claude-personal/ cp -R ~/.claude/file-history ~/.claude-personal/ cp -R ~/.claude/skills ~/.claude-personal/ cp -R ~/.claude/agents ~/.claude-personal/
What each one is:
projects/— per-project conversation transcripts (--resumereads these)history.jsonl— the input prompt history you cycle through with up-arrowfile-history/— per-session file edit historyskills/— your user-defined skills (slash commands, etc.)agents/— your user-defined subagents
Optional: copy settings.json if you've customized hooks, permissions, theme, or model — those carry over cleanly. Skip plugins/, cache/, paste-cache/, ide/, debug/, backups/, sessions/, session-env/, shell-snapshots/, telemetry/, and any auth/credential files — those are profile-specific and shouldn't be shared.
Safety net: prompt on bare claude
To avoid accidentally launching the wrong profile when you absent-mindedly type claude, shadow it with a fish function that forces a choice. Save as ~/.config/fish/functions/claude.fish:
function claude --description "Prompt for personal/work profile, then run claude" echo "Which Claude profile?" echo " 1) personal" echo " 2) work" read --nchars 1 --prompt-str "> " choice echo switch $choice case 1 p CLAUDE_CONFIG_DIR=$HOME/.claude-personal command claude $argv case 2 w CLAUDE_CONFIG_DIR=$HOME/.claude-work command claude $argv case '*' echo "claude: invalid choice '$choice' — expected 1/p (personal) or 2/w (work)." >&2 return 1 end end
command claude bypasses the function so it doesn't recurse into itself. Anything other than 1/p/2/w prints an error to stderr and exits non-zero — no silent fall-through into a default profile. The aliases (claude-personal, claude-work) still work and skip the prompt — useful in scripts.
Notes
- MCP servers are per-profile. If you configure an MCP server in one profile, you'll need to configure it again in the other.
- Plugins, agents, hooks, and settings are per-profile for the same reason.
- Existing
~/.claudedirectory is untouched and unused once the wrapper is in place — everyclaudeinvocation now goes through one of the two profiles.
Verifying
ls -la ~/.claude-personal ~/.claude-work
Each should exist after its first launch.
