Skip to content

Instantly share code, notes, and snippets.

@le-dawg
Created April 22, 2026 17:43
Show Gist options
  • Select an option

  • Save le-dawg/100d14728f93b461bf56c9aec977dca1 to your computer and use it in GitHub Desktop.

Select an option

Save le-dawg/100d14728f93b461bf56c9aec977dca1 to your computer and use it in GitHub Desktop.
Run Multiple Independent Instances of the Same App on macOS (Electron Apps)

macOS App Cloning (Per-Instance Data Isolation, No Keychain)

This is a practical, reality-tested method for running multiple independent instances of the same macOS app with separate local data (sessions, cache, settings, extensions, etc.).

It deliberately avoids false guarantees:

  • This does not create full OS-level isolation
  • This does not isolate Keychain, iCloud, or permissions
  • This works only if the app supports alternate data directories or profiles

If the app ignores custom data paths or is heavily sandboxed, this approach will fail. In that case, use a separate macOS user account.


1. When This Works (and When It Doesn’t)

Works well for:

  • Chromium-based apps (Chrome, Edge, Brave)
  • Many Electron apps (case-by-case)
  • Developer tools (VS Code, etc.)

Works best when the app supports:

  • --user-data-dir
  • built-in profiles
  • portable mode

Does NOT reliably work for:

  • Mac App Store apps (sandboxed)
  • apps using system containers (~/Library/Containers)
  • apps enforcing single-instance locks
  • apps with background daemons or shared services

2. Core Principle

You are not cloning the app.

You are launching the same binary with a different data root.

That is the only mechanism that matters.


3. Directory Structure

Create one isolated root per clone:

mkdir -p "$HOME/AppClones/Work-App"/{home,profile,logs}
mkdir -p "$HOME/AppClones/Personal-App"/{home,profile,logs}

Structure:

AppClones/
  Work-App/
    home/      # optional alt HOME
    profile/   # actual app data
    logs/

4. Locate the Real Executable

Do not rely on open.

Find the actual binary:

ls "/Applications/AppName.app/Contents/MacOS/"

Example:

/Applications/Google Chrome.app/Contents/MacOS/Google Chrome

5. Create Launcher Script

Create:

nano ~/AppClones/Work-App/launch.command

Paste:

#!/bin/zsh
set -euo pipefail

ORIG_HOME="$HOME"
CLONE_ROOT="$ORIG_HOME/AppClones/Work-App"
ALT_HOME="$CLONE_ROOT/home"
PROFILE_DIR="$CLONE_ROOT/profile"
LOG_DIR="$CLONE_ROOT/logs"

mkdir -p "$ALT_HOME" "$PROFILE_DIR" "$LOG_DIR"

APP="/Applications/AppName.app/Contents/MacOS/AppName"

exec env HOME="$ALT_HOME" \
  "$APP" \
  --user-data-dir="$PROFILE_DIR" \
  "$@" \
  >>"$LOG_DIR/stdout.log" 2>>"$LOG_DIR/stderr.log"

Make executable:

chmod +x ~/AppClones/Work-App/launch.command

6. App-Specific Adjustments

Chromium / Chrome / Edge / Brave

Use:

--user-data-dir="$PROFILE_DIR"

This is the official mechanism for isolating browser state.


Firefox

Do NOT use the script method.

Use built-in profiles:

about:profiles

or:

firefox -P

VS Code (Best Case)

Use Portable Mode, not cloning:

Visual Studio Code.app/
code-portable-data/

This keeps all data local to that instance.


Electron Apps

Try:

--user-data-dir="$PROFILE_DIR"

Outcomes:

  • Works → full isolation
  • Ignores flag → not cloneable via this method
  • Forces single instance → not cloneable

7. Create Clickable macOS App (No Dependencies)

Use Script Editor (built-in).

Steps:

  1. Open Script Editor
  2. Paste:
set h to POSIX path of (path to home folder)
do shell script quoted form of (h & "AppClones/Work-App/launch.command") & " >/dev/null 2>&1 &"
  1. Export:

    • File → Export
    • Format: Application
    • Name: Work App.app

8. Install Like a Normal App

mkdir -p ~/Applications
mv "Work App.app" ~/Applications/

Then:

  • Drag to Dock
  • Launch via Spotlight
  • Treat as independent app

9. Verification Checklist

Run both:

  • Original app
  • Clone

Confirm:

Check Expected
Login sessions Different accounts
Cookies/storage Separate
Extensions/plugins Independent
Files written Inside ~/AppClones/.../profile
Logs Written to logs/

Inspect:

ls ~/AppClones/Work-App/profile

10. Debugging

Check logs:

tail -n 100 ~/AppClones/Work-App/logs/stderr.log

Common failures:

Symptom Cause
Same session as original app ignored data dir
Only one instance opens single-instance lock
Data still shared app uses container / external service
App crashes invalid flag

11. Maintenance

Backup:

rsync -a "$HOME/AppClones/" "$HOME/Backups/AppClones/"

Delete clone:

rm -rf ~/AppClones/Work-App

Update app:

  • no change required
  • script still points to original binary

12. Hard Limits (Do Not Ignore)

This method cannot override:

  • macOS App Sandbox
  • app-group containers
  • background services
  • system-level credential storage
  • single-instance enforcement

If any of those apply, the clone is not truly isolated.


13. Simplest Alternative (Often Better)

If the app supports profiles:

  • Chrome → Profiles
  • Firefox → Profiles
  • VS Code → Profiles / Portable Mode

These are:

  • more stable
  • officially supported
  • zero maintenance

14. Only Real “Full Isolation” Option

If you need:

  • separate permissions
  • separate app containers
  • separate OS-level state

Use:

System Settings → Users → Add User

Then enable Fast User Switching.


Bottom Line

This method works when:

  • the app allows a custom data directory

It fails when:

  • the app does not

There is no workaround for that boundary without moving up to OS-level isolation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment