How To Run Two Claude AI Accounts Simultaneously On Mac
Most guides tell you to use environment variables. But there is a cleaner way: install Claude as two separate desktop apps, each with its own isolated config directory, and run both at the same time.
Yes, you can run two Claude accounts at the same time on a Mac. Install Claude Desktop twice as two separate apps. Then launch the second app with --user-data-dir pointed at a separate folder, such as ~/Library/Application Support/Claude-Work. For daily use, wrap the copied app executable so Finder, Spotlight, and Dock launches pass that flag. For Claude Code in the terminal, use a different CLAUDE_CONFIG_DIR for each account. Each install keeps its own login, history, memory, and MCP settings.
The problem
Claude Code stores auth tokens, session history, MCP configs, memory files, and project settings in ~/.claude. If you use two Anthropic accounts, switching means running /login often. That wipes the previous session.
Most workarounds suggest a CLI alias with CLAUDE_CONFIG_DIR set to a different path. That works in the terminal. It does not solve the desktop app problem. Claude Desktop has no built-in account switcher.
The real solution: two app installs
The cleanest approach is to install Claude Desktop twice, as two separate .app bundles on your Mac. macOS treats each bundle as an independent app. You can name the second one Claude Work, Claude 2, or anything that fits your setup.
When you do this, macOS automatically gives each app its own Application Support directory. Claude Desktop picks up ~/Library/Application Support/Claude/ for the first install and ~/Library/Application Support/Claude-Work/ (or whatever you named it) for the second. Credentials, memory, sessions, and MCP configs are entirely separate between the two.
Launching the second app with the right config
The key flag is --user-data-dir, which is an Electron-level argument that tells the app which directory to use for all persistent data. First, create the second copy (otherwise the open command below fails with "Unable to find application named 'Claude 2'"):
cp -R "/Applications/Claude.app" "/Applications/Claude 2.app"Then open that second Claude install and ensure it always points to its own config:
open -n -a "Claude 2" --args --user-data-dir="$HOME/Library/Application Support/Claude-Work"The -n flag forces a new instance even if an app with that name is already running. This is useful for testing, but a normal double-click does not pass --user-data-dir. For daily use, wrap the copied app's executable so the flag is injected automatically whenever you open it from Finder, Spotlight, or the Dock.
Terminal and desktop shortcuts
Typing the full environment variable prefix or the open command every time gets old fast. Four shell aliases reduce each launch to a single word.
For the terminal, each alias points to a separate config directory so the two accounts never share tokens, history, or memory files:
alias claude-personal='CLAUDE_CONFIG_DIR=~/.claude-personal claude'
alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'For the desktop apps, each alias calls open with the right --user-data-dir already attached. The -n flag ensures a new window opens even if that app is already running:
alias open-claude='open -n -a "Claude" --args --user-data-dir="$HOME/Library/Application Support/Claude-Personal"'
alias open-claude-work='open -n -a "Claude Work" --args --user-data-dir="$HOME/Library/Application Support/Claude-Work"'Reload your shell after adding them:
source ~/.zshrcThe first time you run claude-work, type /login to authenticate with your work account. After that, both terminal aliases run in parallel in separate tabs with no interference.
If you prefer shorter names, anything works. A common pattern is cm/cw for the terminal aliases and cmd/cwd for the desktop ones. Pick names you will actually remember.
The desktop aliases require the two app bundles from the next section. Without the wrapper executable, --user-data-dir is silently ignored and both aliases open the same app.
You do not need the aliases if you only need the work account occasionally. You can pass the environment variable inline without setting anything permanently:
CLAUDE_CONFIG_DIR=$HOME/.claude-work claudeChecking which account you are on
With two configs in play it is easy to lose track of which account a terminal session is using. The quickest way to check is to run /status inside the CLI. It shows the logged-in account and plan.
You can also read it from the shell without opening Claude at all:
# Personal (default)
python3 -c "import json,os;print(json.load(open(os.path.expanduser('~/.claude/.claude.json')))['oauthAccount']['emailAddress'])"# Work
python3 -c "import json,os;print(json.load(open(os.path.expanduser('~/.claude-work/.claude.json')))['oauthAccount']['emailAddress'])"If the config directory exists but the email comes back empty, that account has not run /login yet. The directory being present does not mean it is authenticated.
Make sure you are billing to the right account
CLAUDE_CONFIG_DIR isolates which subscription you log into, but one environment variable can quietly bypass all of it: ANTHROPIC_API_KEY.
If ANTHROPIC_API_KEY (or ANTHROPIC_AUTH_TOKEN, or the Bedrock/Vertex equivalent flags) is set in your shell, the CLI uses that key for billing and ignores your subscription login entirely. You can be logged in to your Max account and still be charged per-token against an API key without realizing it.
Check before you start:
echo "API key set? ${ANTHROPIC_API_KEY:+YES}"If it prints YES and you want subscription billing, unset it for that session:
unset ANTHROPIC_API_KEYYou can also confirm the active billing mode by inspecting the billingType field in the config JSON. A value of stripe_subscription means the subscription is active, not an API key.
Make it a real second app: custom name and icon
Launching with a flag works. You can also turn the second install into a separate app with its own name, Dock icon, and notification group. A Mac app is a folder, and its identity lives in Contents/Info.plist.
First, duplicate the app under a new name:
cp -R "/Applications/Claude.app" "/Applications/Claude Work.app"Then give the copy its own identity. CFBundleIdentifier is the key field. Without it, macOS treats both apps as one app. Read the original id first, then set new values on the copy:
defaults read "/Applications/Claude.app/Contents/Info" CFBundleIdentifierplist="/Applications/Claude Work.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleName 'Claude Work'" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName 'Claude Work'" "$plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier 'com.anthropic.claude.work'" "$plist"Swap in your own icon by replacing the .icns the bundle references:
cp "MyIcon.icns" "/Applications/Claude Work.app/Contents/Resources/AppIcon.icns"To make normal opening work, wrap the copied executable. This keeps the app name the same, but forwards every launch to the real Claude binary with --user-data-dir already attached:
app="/Applications/Claude Work.app"
exe="$app/Contents/MacOS/Claude"
real="$app/Contents/MacOS/Claude.real"
mv "$exe" "$real"
printf "%s\n" "#!/bin/zsh" \
'APP_DIR="$(cd "$(dirname "$0")" && pwd)"' \
'exec "$APP_DIR/Claude.real" --user-data-dir="$HOME/Library/Application Support/Claude-Work" "$@"' > "$exe"
chmod +x "$exe"Editing the bundle invalidates Apple's code signature, so you have to re-sign it. Do not reach for codesign --deep here. Apple has deprecated --deep for signing, and on a nested app like Claude (it ships four embedded helper apps and several frameworks) it often mis-orders or skips a helper. That leaves Anthropic's original Developer ID signature on a helper sitting inside an ad-hoc-signed parent, and the mismatch is exactly what produces the broken code signature and unable to find helper app (Electron FATAL) crash some readers have hit.
Sign inside-out instead: every nested framework and helper app first, the loose helper binaries and the renamed real launcher next, and the outer .app last. The find pipes below do all of it, then verify the result so a bad sign fails loudly instead of crashing only when you launch:
app="/Applications/Claude Work.app"
# 1. nested frameworks, then the helper apps (deepest code first)
find "$app/Contents/Frameworks" -name "*.framework" -type d \
-exec codesign --force --sign - {} \;
find "$app/Contents/Frameworks" -name "*.app" -type d \
-exec codesign --force --sign - {} \;
# 2. loose helper binaries + the renamed real launcher
for f in "$app/Contents/Helpers/"* "$app/Contents/MacOS/Claude.real"; do
[ -f "$f" ] && codesign --force --sign - "$f"
done
# 3. the outer app LAST, so its seal covers the freshly signed insides
codesign --force --sign - "$app"
# 4. confirm it will actually launch
codesign --verify --deep --strict "$app" && echo "signature OK"Then refresh the icon and Launch Services caches so macOS picks up the new identity:
lsr="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
"$lsr" -f "/Applications/Claude Work.app"
killall Dock FinderNow open the second app normally, and the wrapper will always point it at its own data directory:
open "/Applications/Claude Work.app"If you prefer a script, I wrapped the full flow into one command — see the companion script at the top of this article.
Troubleshooting and gotchas
Broken code signature / unable to find helper app (Electron FATAL): this is the most common failure, and it almost always means the bundle was signed with codesign --deep (or only the outer .app was re-signed). Either way a nested helper keeps its original signature under an ad-hoc parent and macOS refuses to launch it. Fix it by re-signing inside-out with the find pipes above, then confirm with codesign --verify --deep --strict before launching. Sign with the app fully quit — re-signing a running copy can leave a half-written, broken signature.
Code signing: if the renamed app still refuses to open or Gatekeeper blocks it, you skipped the ad-hoc re-sign in the previous step. Re-run the inside-out sign after any edit to the bundle (icon, plist, or wrapper) — every edit invalidates the seal.
Icon will not change: newer Electron builds reference the icon from an asset catalog (Assets.car) via the CFBundleIconName key rather than a loose AppIcon.icns. If the loose-file swap does not take, set CFBundleIconFile to your .icns with PlistBuddy and delete the CFBundleIconName key, then refresh the caches again.
Updates make the copy go stale: Claude's auto-updater only updates the original Claude.app. Your renamed copy will not update itself, so re-run the duplication (or the script's update mode) after each new release to stay current.
Login goes to the wrong window: Claude authenticates through claude:// deep links, and with two instances open macOS can hand the login to the wrong one. The simplest fix is to fully quit the other app while you sign in to a fresh install.
What stays separate
Each app and CLI alias keeps its own data: auth tokens, account session, history, memory files, project notes, MCP settings, Claude Code permissions, tasks, and hooks.
The only thing that is shared is the Claude Code binary itself (the CLI executable at ~/.local/bin/claude). Both accounts use the same version of the tool. Only the data directories differ.
Key Takeaways
Install Claude Desktop twice for true account isolation at the app level.
Use --user-data-dir to point each app to its own config directory.
Wrap the copied app executable so normal Dock/Finder launches pass --user-data-dir automatically.
Change CFBundleIdentifier (plus name and icon) to get a separate Dock app.
Shell aliases (claude-personal/claude-work for the terminal, open-claude/open-claude-work for the desktop) reduce each launch to one word. Rename them to whatever you will actually remember.
Run source ~/.zshrc after adding an alias so the current terminal session picks it up.
Run /status inside the CLI to confirm which account and plan are active.
Unset ANTHROPIC_API_KEY if it is set and you want subscription billing, not per-token billing.
Re-sign ad-hoc after editing the bundle, and re-clone after each update.
Both accounts can run simultaneously with no logout required.
Frequently asked questions
Can you run two Claude accounts at the same time on a Mac?
Yes. Install Claude Desktop as two separate app bundles, each launched with its own --user-data-dir, or use the CLAUDE_CONFIG_DIR environment variable for the Claude Code CLI. Both accounts then run in parallel with separate logins and no need to log out.
How do I switch between two Anthropic accounts without logging out?
You do not switch at all. Give each account its own isolated config directory (a second Claude Desktop install with --user-data-dir, or a different CLAUDE_CONFIG_DIR for the CLI). Each keeps its own session, so both stay logged in simultaneously.
Where does Claude store its configuration on a Mac?
Claude Code (the CLI) stores everything in ~/.claude. Claude Desktop uses ~/Library/Application Support/Claude. Pointing a second install at a different directory is what makes two accounts independent.
Can I use a personal and a work Claude account simultaneously?
Yes. Run your personal account from the default install and your work account from a second install (or a second CLI alias with its own CLAUDE_CONFIG_DIR). They share only the Claude Code binary; credentials, memory, and settings stay separate.
Can I give the second Claude app its own name and icon?
Yes. Duplicate Claude.app and rename it. Then edit its Info.plist fields: CFBundleName, CFBundleDisplayName, and CFBundleIdentifier. macOS will treat it as a separate app with its own Dock icon and notifications. Replace AppIcon.icns for a custom icon, then re-sign the bundle ad-hoc with codesign. The companion script in this article automates all of it.
Related articles
Comments (2)
Got broken code signature and unable to find helper app (Electron FATAL) when trying to follow your steps for desktop app duplicating
Ah yeah, that one's on the guide, not you. Turns out codesign --deep is flaky with Claude's nested helper apps (Apple actually deprecated it for signing), which is what throws that "unable to find helper app" crash. I just updated the post + the script to sign things inside-out instead - grab the new claude-clone.sh, quit Claude fully, and re-run it. Should sign clean and verify before it even launches now. Thanks for the heads up! 🙏