Run two (or more) fully isolated Claude Desktop instances side by side on macOS — e.g. one signed into your personal account and one into your work account — each with its own color-coded Dock launcher that focuses the existing window instead of spawning duplicates.
This builds on Philipp Stracker's excellent --user-data-dir approach (
write-up) and adds two things:
Recolored icons so you can tell the launchers apart at a glance (blue work / red personal / etc.).- A smart, self-contained launcher that fixes the "every click opens another window" problem.
The most reliable setup is to create a
separate, dedicated instance for each account — including your "personal" one — and stop using Claude's built-in default profile for day-to-day use.Don't try to make one launcher target the shared default profile.Why: Claude has
no per-profile single-instance lock, so two processes can run on one profile at once — andonly theIf a "personal" launcher points at the default profile (which the stock Claude icon also uses), you end up with duplicate, logged-out windows. Giving each account its own dir guaranteesfirstinstance on a profile can use its login database. Every additional instance on that same profile shows up logged out.one profile → one instance → always logged in, and makes the focus-don't-duplicate logic rock-solid.Already logged into the default profile and don't want to re-auth? See
[Migrating an existing login]— you can copy your current profile into the new dedicated dir.
Claude Desktop is an Electron app. Electron's --user-data-dir
flag points the app at a completely separate profile folder (config, sessions, auth tokens, MCP servers, Cowork data):
open -n -a "/Applications/Claude.app" --args --user-data-dir="$HOME/.claude-instances/work"
A tiny macOS .app
"wrapper" just runs that command, so it shows up in Launchpad/Dock like a
normal app. Each wrapper stores its instance name in Contents/MacOS/config.sh
and runs
Contents/MacOS/claude-launcher
.
The naive launcher uses open -n
— the -n
flag means "open a NEW instance, even if one is already running." Claude has no per-profile single-instance lock, so every click spawns another process against the same profile dir. That stacks up duplicate windows and risks corrupting the shared profile.
The smart launcher in this gist fixes it. On click it inspects that specific instance
(matched by --user-data-dir
; for the default instance, the main process that has no
--user-data-dir
) and does one of three things:
Running with a window→ focuses that process's window by PID via System Events. No duplicate.** Running but windowless**→ opens a fresh window. Claude keeps its main process alive after you close the window, and a windowless instancecannotbe re-shown per-instance (all instances share one bundle id, soopen -a
/ "activate" can't target it). We deliberatelydo not kill the windowless process: it is often windowless precisely because it's still doing background work (e.g. a chat that's "thinking"), and killing it would lose that work. The leftover windowless process is harmless and goes away when you fullyQuit (⌘Q) Claude.Not running→ launches fresh withopen -n
.
How "has a window?" is detected: a live window shows up as one or more --type=renderer
processes for that profile; closing the window drops that count to 0.
So "always click the launcher you want" reliably focuses-or-launches the right instance, even after you've closed its window.
Tip:to keep the focus-don't-relaunch behavior working,close Claude with ⌘W(close window, app keeps running) when you want it to stay live, and⌘Qwhen you truly want it gone.
The recolored icon lives on the launcher you click. Because all instances share the one
/Applications/Claude.app
binary, while running they all show the same stock Dock icon and the name "Claude" — the color only marks the launcher. The reliable in-app tell is the signed-in account. (Truly distinct running Dock icons would require a full standalone copy of Claude.app.)
chmod +x make-claude-instance.sh
./make-claude-instance.sh work Work 135
./make-claude-instance.sh personal Personal -7
- The
first time a launcher focuses a running window, macOS asks*"Claude … wants to control System Events"*→ clickOK(one time per launcher). Give every instance its own isolated dir— use a real name like
personal
/work
,notdefault
. One profile → one instance (see the ⭐ callout above for why).- The instance name
is still supported (it uses Claude's built-in profile with nodefault
--user-data-dir
) for folks who want one launcher onto the stock profile — but it's only safe if that profile isneverrun by more than one instance at a time (i.e. don't also use the stock Claude icon). A dedicated dir is the robust, recommended choice.
| Look | hueShift | satGain (optional) |
|---|---|---|
| Stock orange | 0 |
|
1.0 |
||
| Red-orange | -7 |
|
1.08 |
||
| Green | +80 |
|
1.0 |
||
| Blue | +135 |
|
1.0 |
||
| Purple | +170 |
|
1.0 |
Icon recoloring is optional — it only runs if Python 3 + Pillow
are available (pip install Pillow
). Without them you still get a fully working launcher with the stock icon.
If you're already signed into Claude's default profile and want your new dedicated instance to start out logged in (with your settings, MCP servers, and sessions intact), copy the profile across while Claude is fully quit so the copy is consistent:
ps -axo command | grep "[C]laude.app/Contents/MacOS/Claude" # should print nothing
rsync -a \
--exclude 'Singleton*' \
--exclude 'Cache' --exclude 'Code Cache' --exclude 'GPUCache' \
--exclude 'DawnGraphiteCache' --exclude 'DawnWebGPUCache' --exclude 'ShaderCache' \
--exclude 'Crashpad' --exclude 'blob_storage' \
"$HOME/Library/Application Support/Claude/" "$HOME/.claude-instances/personal/"
Your original default profile is left untouched (the stock Claude icon still opens it). The auth token lives in the copied profile (and/or the shared macOS Keychain), so the new instance should launch already signed in. If it doesn't, just sign in once — it sticks from then on.
Heads-up on size: the local-agent / Cowork runtime lives in a
vm_bundles/
folder that can bemany GB. The copy above includes it. To save disk, you canrm -rf
thevm_bundles
folder in the new dir afterward — it re-downloads on demand the next time you use that feature.
ps -axo pid,command | grep "[C]laude.app/Contents/MacOS/Claude"
rm -rf "/Applications/Claude Work.app"
rm -rf "$HOME/.claude-instances/work"
— builds themake-claude-instance.sh
.app
wrapper (Info.plist, config, smart launcher) and optionally recolors the icon.— the self-contained smart launcher template (embedded into each wrapper).claude-launcher
— hue/saturation recolor of therecolor-icon.py
.icns
(used by the helper; needs Pillow).
Core --user-data-dir
isolation technique by Philipp Stracker. Smart focus-or-launch behavior and icon recoloring added here.