Pulse · macOS · build from source v0.1.0 · source

Install Pulse on macOS

Build from source · 6 steps · no official build today

Run Pulse on macOS by building it from source. There is no official macOS build today. Pulse is developed and tested primarily on Windows, and the community has ported the source to Apple Silicon and Intel. Expect rough edges; if a step fails, open a GitHub issue and include the error output.

Two artifacts at the end: a .app bundle that runs from the Finder, and a .dmg that drags the same bundle into /Applications. Both are unsigned — Gatekeeper warns on first run, and the bundle has to be opened via the right-click “Open” menu the first time.

Before you start

Apple Silicon or Intel

Pulse builds natively on M1, M2, and M3. Intel works the same way; Rosetta 2 is not required for the build itself.

Apple Silicon (M1 / M2 / M3 / M4)

arm64-apple-darwin

Native aarch64-apple-darwin build. The Rust toolchain and Tauri both target the host architecture automatically. The output .app is a universal-or-arm64-only bundle; check with file pulse-desktop.app/Contents/MacOS/pulse-desktop after the build.

Verify the host with uname -m — expect arm64 on Apple Silicon.

Intel (x86_64)

x86_64-apple-darwin

Native x86_64-apple-darwin build. No Rosetta required — the Rust toolchain and Tauri both produce a real x86_64 binary. The build is slower on Intel hardware (no Apple Silicon accelerators) but the artifact runs the same way.

Intel Macs that need to run Pulse on an Apple Silicon host via Universal build: cross-compile with cargo build --target aarch64-apple-darwin after rustup target add aarch64-apple-darwin. Universal binary packaging is not part of the default tauri build flow.

Step 1

Prerequisites

Five toolchain pieces. Versions are minimums — newer is fine.

  • Xcode Command Line Tools. Cocoa and the macOS SDK live behind the CLT install. Run xcode-select --install in Terminal and accept the dialog. The install is about 700 MB and finishes in a few minutes on a modern Mac. Verify with xcode-select -p — expect /Library/Developer/CommandLineTools.
  • Node.js 20 or newer. The frontend is plain TypeScript on Vite. Install via nodejs.org (the macOS pkg installer is the simplest path) or via Homebrew (brew install node@20). Check with node --version.
  • Rust 1.75 or newer. Tauri 2 needs the 1.75 toolchain. Install via rustup.rs: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. Check with rustc --version.
  • Homebrew (optional but useful for git, pkg-config, and other utilities). Install from brew.sh: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)". macOS 13+ ships git in the CLT, so Homebrew is not strictly required.
  • git for cloning the repository. Bundled with the Xcode Command Line Tools on macOS 13 and newer. On older macOS, install via Homebrew (brew install git) or Apple's developer tools.
Step 2

Tauri system dependencies

No extra system packages — Cocoa and WebKit ship with macOS, and the Xcode Command Line Tools cover the rest.

On macOS the Tauri toolchain relies on the system frameworks that ship with the OS: Cocoa, WebKit, and CoreFoundation. The build links against the macOS SDK that the Xcode Command Line Tools install. There is no apt-equivalent step here — no brew install of system packages is required.

One environment variable to know: MACOSX_DEPLOYMENT_TARGET. The repo pins it via Cargo.toml and the tauri.conf.json minimumSystemVersion field. If a downstream toolchain disagrees (an older Xcode CLT, for example), set it explicitly in the shell before running tauri build:

export MACOSX_DEPLOYMENT_TARGET=11.0
npm run tauri build

The default target matches the macOS Big Sur baseline (11.0). Big Sur and newer are supported; older macOS releases fall outside the build matrix.

Step 3

Clone the repository

The macOS build lives in the pulse-desktop subdirectory of the main repo.

git clone https://github.com/TimesNuRoman/pulse.git
cd pulse/pulse-desktop

The monorepo holds Pulse for Windows, the Android app, and the shared data model. The Tauri app is in pulse-desktop. The rest of this guide assumes the working directory is that folder.

Step 4

Install npm dependencies

JavaScript dependencies and the Tauri CLI. First run takes 30 to 90 seconds on a fast connection.

npm install

The install pulls the Vite frontend, the Tauri 2 JavaScript bindings, and the Ollama client. The Rust toolchain handles the backend on the first tauri dev run, not during npm install.

Step 5

Run the dev build

Compiles the Rust backend and opens the dev window. First build is 3 to 5 minutes; later runs are incremental.

npm run tauri dev

The first run downloads and compiles every Tauri dependency — the Rust crates that bind to Cocoa, WebKit, and the Vite plugins. Build output streams to the terminal; the Pulse window appears once the compile finishes.

Edits to TypeScript files hot-reload. Edits to Rust files trigger an incremental rebuild of the affected crate. The dev window uses the same Ollama runtime as production, so any local model that works on Windows works here too.

On first launch macOS asks whether to allow Pulse to access the network (Ollama on localhost:11434). Click Allow. The same dialog reappears for the microphone when voice input is enabled in Settings.

Step 6

Build the production artifacts

Two outputs in src-tauri/target/release/bundle/: a .app bundle and a .dmg installer.

npm run tauri build

The build pipeline produces a .app bundle and a .dmg that drags the same bundle into /Applications. The full output tree:

  • App bundlesrc-tauri/target/release/bundle/macos/Pulse.app
  • DMG installersrc-tauri/target/release/bundle/dmg/Pulse_0.1.0_aarch64.dmg (or x64 on Intel)
  • Raw binarysrc-tauri/target/release/pulse-desktop (run directly, no bundle)

The .dmg opens in Finder and shows a window with the Pulse.app and an alias to /Applications. Drag the bundle into Applications to install. The .app itself is a directory that can be copied anywhere and double-clicked to run.

Neither artifact is signed. Gatekeeper warns on first run. The right-click “Open” menu is the documented workaround; subsequent launches go through normally once the binary is on the system’s approved list.

Troubleshooting

Things that go wrong

Four issues that come up most often, and the fix for each.

  • Build fails with xcrun: error: invalid active developer path. The Xcode Command Line Tools are missing or misconfigured. Run xcode-select --install and re-open the Terminal so the new PATH is picked up. If the error persists: sudo xcode-select --reset.
  • Cargo errors with failed to run custom build command for ring or other C deps. The C compiler is missing or stale. xcode-select --install fixes it. On older macOS (10.15 Catalina) the bundled clang may be too old; the supported minimum is macOS 11 (Big Sur) with the latest Xcode CLT.
  • Rust version too old: error: package `tauri v2.x` requires Rust 1.77.2. The repo's rust-toolchain.toml pins the minimum Rust. Update via rustup update, or accept the toolchain prompt and let rustup download it. A Homebrew-installed rustc (brew install rust) is a separate toolchain from rustup; use rustup to avoid version mismatches.
  • Apple Silicon Mac produces an Intel-only .app. rustup target list --installed shows the active targets. If only x86_64-apple-darwin is listed, add the host arch with rustup target add aarch64-apple-darwin and re-run npm run tauri build. The default Tauri 2 config inherits the host triple, so this is only a problem on misconfigured CI or manually-edited ~/.cargo/config.toml.
  • Ollama fails to start inside the app. The bundled Ollama runtime ships only on the Windows installer. On macOS, install Ollama via Homebrew (brew install ollama) or the macOS download and verify it with ollama --version before launching Pulse.
Honest note

Known limitations

The macOS port is a community build. Some things on Windows do not work here yet.

  • No code signing. The .app and .dmg are unsigned. Gatekeeper warns on first run with “Pulse.app” cannot be opened because the developer cannot be verified. The fix is documented in the Troubleshooting section above (right-click → Open). An Apple Developer ID certificate is required for notarization, and that path is not part of this build.
  • No notarization. Notarization requires an Apple Developer team and a signed upload to notarytool. The repo does not include a notarization step. Users on the latest macOS may need to override Gatekeeper via System Settings → Privacy & Security.
  • No auto-update. Pulse for Windows uses a signed update manifest under /updates/desktop.json. The macOS build does not have an update channel — re-run npm run tauri build and reinstall to upgrade.
  • Voice input is Windows-only. The panel's mic button uses the Windows SpeechRecognition API. On macOS, the button is disabled.
  • Universal binary is not part of tauri build. The default build produces a single-architecture .app matching the host triple. A true universal binary (arm64 + x86_64) needs cargo lipo and a manual merge step; this is left to the fork-and-PR flow.
Get help

Get help

One channel: GitHub Issues. Include the error output and the macOS version.

Open an issue on the pulse issue tracker and tag it macos. The minimum reproduction set is: macOS version (output of sw_vers), Mac model (M1 / M2 / M3 / Intel), Node version, Rust version, the failing tauri dev or tauri build output, and the contents of ~/.cargo/registry/cache/ if the build failed on a specific crate.

For Gatekeeper / signing questions, the Apple Developer account docs cover Developer ID and notarization prerequisites. The Pulse build does not bundle signing identities, so a clean Apple Developer enrollment is a prerequisite for a self-distributed signed build.

Source patches go through the standard fork-and-pull-request flow on the pulse-desktop tree. CI runs on the latest macOS and an Intel runner; a patch that breaks either gets flagged before merge.