Run multiple isolated instances of any Electron app: the user-data-dir trick
Launch Slack while Slack is running and you get the existing window. Same for Discord, Teams, WhatsApp, Obsidian: Electron apps are single-instance by design. That's usually what you want, until you need two of them: two accounts, two clients, work and personal, signed in side by side without a shared notification stream.
There's one mechanism that does this for practically every Electron and Chromium app at once, and it's worth understanding rather than memorizing per-app recipes.
Identity is a directory
A Chromium-based app keeps everything that makes it your copy (sign-ins, cookies, cache, local settings) in its user data directory. One flag moves it:
<app> --user-data-dir=<some-directory>The single-instance behavior is keyed on that directory too. Electron's requestSingleInstanceLock() takes a lock inside the user data dir; a second launch finds the lock, hands its arguments to the running process, and exits. Different directory, different lock, so two launches with two profile directories are two fully independent processes: separate windows, separate sign-ins, separate notification identities. Nothing is shared but the binary, so updates still apply once.
This works because most Electron apps pass command-line switches straight down to the Chromium layer, which is where --user-data-dir is handled; the app author doesn't have to support it, and usually doesn't know you're using it. The same flag isolates a browser (chrome --user-data-dir=... is how Chrome profiles-as-separate-processes work), Discord, Teams, or a second copy of whatever Electron app your workflow centers on.
The recipe
Pick a directory per identity and launch with the flag; the directory is created and walks you through sign-in on first run:
# Windows (classic per-user installs live under %LOCALAPPDATA%\<app>)
%LOCALAPPDATA%\slack\slack.exe --user-data-dir=%APPDATA%\SlackProfiles\client-a
# macOS (force a new instance with -n, pass flags through --args)
open -na Slack --args --user-data-dir="$HOME/Library/Application Support/SlackProfiles/client-a"
# Linux
/usr/bin/slack --user-data-dir="$HOME/.config/SlackProfiles/client-a"Bake the flag into whatever launches things for you: a Windows shortcut target, a macOS alias or Automator app, a Linux .desktop entry. The multiple Slack instances post is the fully worked, per-OS version of this recipe.
The gotchas, all shared too
Because the mechanism is shared, the sharp edges repeat across apps:
Launch the real executable. Launcher stubs (Squirrel's
Update.exe), Start Menu tiles, and dock icons don't forward extra arguments. On Windows, a Microsoft Store install has no classic exe path at all; launch its app-execution alias (%LOCALAPPDATA%\Microsoft\WindowsApps\<app>.exe), which does pass arguments through.Deep links go to the default instance. The OS routes protocol links (
slack://,discord://) to the single registered handler, so a browser-based sign-in you started in an isolated instance completes in the default one. The fix is delivering the link to the right instance yourself; a launch with the profile's--user-data-dirplus the URL forwards it through the same single-instance handoff:text<app> --user-data-dir=<profile-dir> "slack://<the-deep-link>"When the sign-in page offers a copyable link, right-click and copy it. Many no longer do; the robust fix is registering a router of your own as the scheme's default app (a per-user
RegisteredApplicationsentry picked once in the OS default-apps settings, which outranks even a Store package's claim) and letting it forward each link to the instance you pick.Memory. Each instance is a full Chromium runtime, a few hundred MB; one per client scales, one per channel doesn't.
Dock and taskbar grouping. On Linux under Xorg, add
--class=<name>and a matchingStartupWMClassso each instance groups under its own icon; Windows and macOS give each process its own taskbar and Dock presence naturally.
Where the instances land
Isolation gets really comfortable combined with virtual desktops: one desktop per identity, that identity's instance maximized on it, a hotkey to jump. On Windows, that arrangement (and the deep-link routing above) can be declared as config; the windows role treats any app carrying --user-data-dir as a named profile, deploys hotkeyed workspace launchers, and registers the Virtual Desktop Router that forwards each link to the isolated instance of the workspace you're in. The mechanics behind that are in One hotkey per client.
One directory per identity, one flag per launch: that's the entire trick, and it works on almost everything you run.