# I got tired of logging in and out of Claude Code, so I built a one-command account switcher

> 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: 2026-10-03 11:25:10+00:00

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.

Sign 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.

So I fixed it. The result is **cc-switch**, and the whole thing is one command:

```
ccp use personal
```

Every `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:

```
  Claude Code profiles
  --------------------
  * default                   alice@company.com
    personal   [shared]       alice@gmail.com
    client-x   [isolated]     alice@client-x.com
```

I 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.

So a "profile" in cc-switch is literally a directory:

```
~/.claude-profiles/
  personal/    ← its own login
  client-x/    ← its own login
~/.claude      ← your original account, untouched ("default")
```

`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:

```
# terminal 1
ccp run work

# terminal 2
ccp run personal -p "summarise yesterday's changes"
```

I use that far more than I expected to.

The 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.

For 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.

The 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.

If you *do* want a walled-off environment, you just say so:

```
ccp add client-x --isolated
```

You 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.

This is the part I actually want people to read, because it's a general Windows/PowerShell gotcha.

My 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.

In 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.

If 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.

One line, no clone:

**Windows (PowerShell)**

```
irm https://raw.githubusercontent.com/petersonsenadevs/claude-code-switch/main/install.ps1 | iex
```

**Linux / macOS**

```
curl -fsSL https://raw.githubusercontent.com/petersonsenadevs/claude-code-switch/main/install.sh | bash
```

Then:

```
ccp add personal          # new profile, shares your chats
ccp login personal        # opens claude: sign in, then /exit
ccp use personal          # you're switched
ccp list                  # every profile, with the email signed in on each
```

It'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.

`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?
The 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.
