{"slug": "i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command", "title": "I got tired of logging in and out of Claude Code, so I built a one-command account switcher", "summary": "A developer built cc-switch, a one-command CLI tool that lets users switch between multiple Claude Code accounts by exploiting the CLAUDE_CONFIG_DIR environment variable, which Claude Code uses as the root for credentials, settings, and session transcripts. The tool creates separate profile directories for each account and supports a \"shared\" mode that symlinks chat folders back to the original config so conversation history persists across logins. The developer also documented a Windows/PowerShell hazard: Remove-Item -Recurse follows NTFS junctions and would have deleted the real chat history, fixed by deleting the reparse points before recursing.", "body_md": "Quick confession: last week I logged out of my work Claude Code account four times in one afternoon. Nothing was broken. I just have a second account for personal projects, and Claude Code can only be logged into one of them at a time.\n\nSign in with the personal account and the work one is gone. Sign back in with work and personal is gone. Every switch is a browser tab, an OAuth dance and about forty seconds of my life. Multiply that by \"I switch contexts a lot\" and you get a genuinely annoying week.\n\nSo I fixed it. The result is **cc-switch**, and the whole thing is one command:\n\n```\nccp use personal\n```\n\nEvery `claude` you launch after that runs under the personal account. `ccp use work` flips it back. No re-login, no browser, no forty seconds. And `ccp list` tells you who is who:\n\n```\n  Claude Code profiles\n  --------------------\n  * default                   alice@company.com\n    personal   [shared]       alice@gmail.com\n    client-x   [isolated]     alice@client-x.com\n```\n\nI expected to need something hacky with credential files. I didn't. Claude Code reads an environment variable called `CLAUDE_CONFIG_DIR` and uses it as the root for *everything* it stores: credentials, settings, session transcripts, the lot. Point it at a different folder and you get a completely separate identity.\n\nSo a \"profile\" in cc-switch is literally a directory:\n\n```\n~/.claude-profiles/\n  personal/    ← its own login\n  client-x/    ← its own login\n~/.claude      ← your original account, untouched (\"default\")\n```\n\n`ccp use <name>` sets the variable for the current shell *and* persists it for new terminals. `ccp run <name>` sets it for a single invocation only, which means two terminals can talk to two different accounts at the same time:\n\n```\n# terminal 1\nccp run work\n\n# terminal 2\nccp run personal -p \"summarise yesterday's changes\"\n```\n\nI use that far more than I expected to.\n\nThe first version worked great for about ten minutes. Then I opened a project under the personal profile and my conversation history was empty. Of course it was: transcripts live in `projects/` inside the config dir, and the new profile had its own brand new, empty one.\n\nFor some setups that's exactly what you want (a clean-room profile for a client). For my day-to-day it was terrible. I wanted the *login* separated, not my memory of what I was doing yesterday.\n\nThe fix turned out to be clean. On a **shared** profile, cc-switch replaces the chat folders (`projects/`, `sessions/`, `plans/`, `tasks/`, `file-history/`) and `history.jsonl` with links back into `~/.claude`: NTFS junctions and a hardlink on Windows, plain symlinks on Linux and macOS. Credentials and settings stay per profile, chats are one pool, and `claude --resume` shows the same list whichever account you're on.\n\nIf you *do* want a walled-off environment, you just say so:\n\n```\nccp add client-x --isolated\n```\n\nYou can flip a profile between the two modes later with `ccp link` and `ccp unlink`. Nothing gets deleted either way: `unlink` gives the profile its own empty folders and leaves the shared history where it is.\n\nThis is the part I actually want people to read, because it's a general Windows/PowerShell gotcha.\n\nMy first `ccp remove` was the obvious thing: `Remove-Item -Recurse -Force <profile dir>`. On a *shared* profile, that directory is full of junctions pointing at `~/.claude`. And `Remove-Item -Recurse` will happily walk straight through a junction and delete the contents of the target.\n\nIn other words, \"remove the test profile\" would have wiped my entire real chat history. I only caught it because I was being paranoid in testing: I made a throwaway profile and counted the project folders on both sides before and after. The fix is to delete the links themselves first (`DirectoryInfo.Delete()` on a junction removes only the reparse point, not what it points to) and *then* recurse into whatever is left. `rm -rf` on Linux doesn't follow symlinks, so the bash version was never at risk, but it does the same explicit dance anyway.\n\nIf you write any tool that creates junctions on Windows: test your delete path against a directory you'd be sad to lose. I got lucky. You might not.\n\nOne line, no clone:\n\n**Windows (PowerShell)**\n\n```\nirm https://raw.githubusercontent.com/petersonsenadevs/claude-code-switch/main/install.ps1 | iex\n```\n\n**Linux / macOS**\n\n```\ncurl -fsSL https://raw.githubusercontent.com/petersonsenadevs/claude-code-switch/main/install.sh | bash\n```\n\nThen:\n\n```\nccp add personal          # new profile, shares your chats\nccp login personal        # opens claude: sign in, then /exit\nccp use personal          # you're switched\nccp list                  # every profile, with the email signed in on each\n```\n\nIt's plain shell (a PowerShell module and a bash script) with no dependencies and no daemon. It doesn't wrap or patch `claude`; it only sets a variable the CLI already respects. Profile names autocomplete with Tab, and `ccp update` pulls the latest version when there is one.\n\n`ccp list` shows the right account on each profile (or doesn't), I'd really like to hear about it in an issue.`--resume` behave. `settings.json` and MCP configs stay per profile on purpose. Would you share anything else?\nThe repo is here: **[github.com/petersonsenadevs/claude-code-switch](https://github.com/petersonsenadevs/claude-code-switch)**, MIT licensed. If it saves you the forty seconds, a star helps other people find it.", "url": "https://wpnews.pro/news/i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command", "canonical_source": "https://dev.to/r3v3rs3/i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command-account-switcher-3ea3", "published_at": "2026-10-03 11:25:10+00:00", "updated_at": "2026-10-03 11:38:33.548395+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents"], "entities": ["Claude Code", "cc-switch", "Anthropic", "PowerShell", "Windows", "CLAUDE_CONFIG_DIR"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command", "markdown": "https://wpnews.pro/news/i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command.md", "text": "https://wpnews.pro/news/i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command.txt", "jsonld": "https://wpnews.pro/news/i-got-tired-of-logging-in-and-out-of-claude-code-so-i-built-a-one-command.jsonld"}}