Building LocalVoiceAI from source gives you full control over the binary — you can modify key bindings, swap Whisper models, patch the CGo layer, or pin to a specific commit. The build is a standardDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/npateriya/LocalVoiceAI/llms.txt
Use this file to discover all available pages before exploring further.
go build invocation with CGo enabled and a set of Homebrew-provided libraries linked in. The entire process takes a few minutes on a fresh machine.
Prerequisites
Before building, make sure you have the following on your Apple Silicon Mac:Apple Silicon Mac (M1+)
Required for the Metal GPU backend used by
ggml-metal. Intel Macs are not supported.macOS 14 Sonoma or later
Required for the
CGEventTap API behaviour and LaunchAgent compatibility used by LocalVoiceAI.Go 1.25.5+
Install with
brew install go. The module requires go 1.25.5 as declared in go.mod.Xcode Command Line Tools
Provides
clang and the macOS SDK headers needed by CGo. Run xcode-select --install.portaudio, whisper-cpp, and pkg-config, and all Homebrew-provided libraries are expected at /opt/homebrew/ (the default ARM64 prefix).
Build and Install
Install Homebrew dependencies
make setup also creates three symlinks in /opt/homebrew/lib/ that the linker expects:Homebrew’s
whisper-cpp formula ships ggml as a single consolidated libggml.dylib. The CGO_LDFLAGS in the Makefile link against named per-backend libraries (-lggml-cpu, -lggml-metal, -lggml-blas), so these symlinks are necessary for the linker to resolve all -l flags without errors.Build and install
- Compiles the binary with
go build -o localvoice ./cmd/localvoice/ - Ad-hoc codesigns the local artifact:
codesign -s - --force localvoice - Copies it to
~/.local/bin/localvoiceand re-signs the installed copy - Generates
~/Library/LaunchAgents/com.localvoiceai.localvoice.plistfrom the template (substituting the install path) - Loads the LaunchAgent with
launchctl load
make install completes, follow the on-screen instructions to grant Accessibility and Input Monitoring permissions in System Settings → Privacy & Security. Both must be enabled before starting the service.Start the service
launchctl start com.localvoiceai.localvoice. The service starts as a LaunchAgent — independent of any terminal session. The plist sets RunAtLoad=false, so the service does not start automatically after launchctl load or after a reboot; you must start it explicitly with make start each time. Logs are written to /tmp/localvoice.log:CGo Build Flags Explained
The Makefile sets these environment variables for everygo build invocation:
| Flag | Reason |
|---|---|
-I/opt/homebrew/include | Adds Homebrew’s include path so CGo’s clang invocation can find whisper.h, portaudio.h, and other C headers |
-L/opt/homebrew/lib | Tells the linker where to find Homebrew’s .dylib files at link time |
-lwhisper | Links libwhisper.dylib — the whisper.cpp C API (used at runtime by whisper-cli) |
-lggml -lggml-base | Core ggml tensor library and its base layer |
-lggml-cpu | CPU backend for ggml |
-lggml-metal | Metal GPU backend — required for Apple Silicon GPU acceleration |
-lggml-blas | Accelerate/BLAS-backed matrix operations |
-framework Accelerate | Apple’s high-performance BLAS/LAPACK framework, used by the ggml-blas backend |
-framework Metal | Required by the ggml-metal backend to compile and dispatch Metal shaders |
-framework Foundation | Objective-C runtime used internally by Metal and CoreFoundation |
-framework CoreGraphics | Required by CGEventPost and CGEventTap in the CGo key-monitoring and paste code |
Release builds produced by the CI workflow (The regular
.github/workflows/release.yml) add an extra linker flag to embed the version string:make build target does not include -ldflags — it compiles without a version string. This is intentional; the embedded version is only meaningful for tagged releases distributed via GitHub Releases.main.go also directly links three additional frameworks via #cgo LDFLAGS:
- ApplicationServices — umbrella framework that includes
CGEventTap,CGEventPost, and the Core Graphics event API - CoreFoundation — provides
CFRunLoop,CFMachPort, andCFRunLoopSourceused in the event thread - Carbon — provides the
kVK_*virtual key constants (e.g.,kVK_Command,kVK_ANSI_V) used when synthesizing keystrokes
Codesigning
Every build applies an ad-hoc signature to the binary:-s - flag means “sign with an ad-hoc identity” (no Developer ID certificate required). --force replaces any existing signature.
macOS requires a valid code signature on any binary that requests Accessibility or Input Monitoring entitlements. An ad-hoc signature satisfies this requirement without an Apple Developer account. The signature is applied twice per make install: once to the local ./localvoice build artifact, and once to the installed copy at ~/.local/bin/localvoice.
Go Module
The module is declared asgithub.com/npateriya/LocalVoiceAI in go.mod and requires Go 1.25.5. LocalVoiceAI has exactly one external Go dependency:
CGEventTap, CGEventPost, CFRunLoop, pbcopy subprocess, WAV encoding, model download — is implemented using the Go standard library and CGo bindings against macOS system frameworks. There is no Objective-C and no Swift.
Makefile Reference
| Target | Description |
|---|---|
make setup | Install Homebrew dependencies (portaudio, whisper-cpp, pkg-config) and create libggml-*.dylib symlinks |
make build | Compile the binary only; output is ./localvoice in the repo root |
make install | Build + codesign + copy to ~/.local/bin/ + install and load the LaunchAgent |
make update | Rebuild + codesign + reinstall binary + restart the service (re-grant permissions after) |
make start | Start the LaunchAgent (launchctl start com.localvoiceai.localvoice) |
make stop | Stop the LaunchAgent (launchctl stop com.localvoiceai.localvoice) |
make reload | Reload plist from template and restart — use when changing the plist without a binary change |
make status | Show LaunchAgent status via launchctl list | grep com.localvoiceai.localvoice |
make uninstall | Unload and remove the LaunchAgent plist and the installed binary |
make clean | Remove the local ./localvoice build artifact |