Skip to main content

macOS developer setup

Build and run the OpenClaw macOS application from source.

Prerequisites

  • Xcode 26.2+ (Swift 6.2 toolchain), on the latest macOS available in Software Update.
  • Node.js 24 & pnpm for the gateway, CLI, and packaging scripts. Node 22.19+ also works.

1. Install dependencies

pnpm install

2. Build and package the app

./scripts/package-mac-app.sh
Outputs dist/OpenClaw.app. Without an Apple Developer ID certificate, the script falls back to ad-hoc signing. For dev run modes, signing flags, and Team ID troubleshooting, see apps/macos/README.md. Fast dev loop from repo root: scripts/restart-mac.sh (add --no-sign for ad-hoc signing; TCC permissions do not stick with --no-sign).
Ad-hoc signed apps may trigger security prompts. If the app crashes immediately with “Abort trap 6”, see Troubleshooting.

3. Install the CLI and Gateway

The packaged app embeds the canonical scripts/install-cli.sh installer. On a fresh profile, choose This Mac during onboarding; the app installs the matching user-space CLI and runtime before starting the Gateway wizard. For manual development recovery, install the matching CLI yourself:
npm install -g openclaw@<version>
pnpm add -g openclaw@<version> and bun add -g openclaw@<version> also work. Node remains the recommended runtime for the Gateway itself.

Troubleshooting

Build fails: toolchain or SDK mismatch

The macOS app build expects the latest macOS SDK and the Swift 6.2 toolchain (Xcode 26.2+).
xcodebuild -version
xcrun swift --version
If versions don’t match, update macOS/Xcode and re-run the build.

App crashes on permission grant

If the app crashes when you try to allow Speech Recognition or Microphone access, it may be a corrupted TCC cache or signature mismatch.
  1. Reset TCC permissions for the debug bundle id:
    tccutil reset All ai.openclaw.mac.debug
    
  2. If that fails, temporarily change BUNDLE_ID in scripts/package-mac-app.sh to force a clean slate from macOS.

Gateway “Starting…” indefinitely

Check whether a zombie process holds the port:
openclaw gateway status
openclaw gateway stop

# If you're not using a LaunchAgent (dev mode / manual runs), find the listener:
lsof -nP -iTCP:18789 -sTCP:LISTEN
If a manual run holds the port, stop it (Ctrl+C), or kill the PID found above as a last resort.