Reference

Build & release

How VoiceFlow is compiled and packaged — Electron Forge with Vite for the app, Cargo for the native listener, and a GitHub Action for signed DMG releases.

Bundler

Electron Forge + Vite

Native

Cargo release build

Output

DMG + ZIP (darwin)

Toolchain

Electron Forge + Vite

The Forge Vite plugin builds four bundles: main, preload, and two renderers (main_window and overlay_window).

Cargo

The Rust key listener is compiled to a release binary for the target triple and copied into resources/binaries.

TypeScript

Typecheck with tsc --noEmit; the CI runs this before building distributables.

Makers

maker-zip and maker-dmg (ULFO format) produce the darwin artifacts.

Build scripts

package.json scripts
npm start      # build native listener, then electron-forge start
npm run package  # build native listener, then forge package
npm run make     # build native listener, then forge make (DMG + ZIP)
npm run lint
npm run typecheck

Every run first invokes build:native:key-listener, which shells out to Cargo:

native build (per platform)
cargo build --release \
  --manifest-path native/global-key-listener/Cargo.toml \
  --target aarch64-apple-darwin        # or x86_64-* / windows

# then the compiled binary is copied to resources/binaries/

TARGET_ARCH

Set TARGET_ARCH=arm64 (or x64) to build the native binary for a specific macOS architecture; it defaults to the host arch.

Packaging

  • asar: true packs the app; the native binary and assets ship as extraResourceso they're reachable at runtime.
  • In a packaged build the listener is resolved from process.resourcesPath/binaries; in dev it's read from the Cargo target directory.
  • The worklet and other renderer assets are bundled by Vite; the audio worklet in particular is inlined to survive asar packaging.

Release automation

A GitHub Action builds and publishes the DMG when a v* tag is pushed (or on manual dispatch):

  1. 01Set up Node & RustNode 20 with npm cache, plus the aarch64-apple-darwin Rust target on a macOS runner.
  2. 02Install & typechecknpm ci, then npm run typecheck as a gate.
  3. 03Build the native binary & makeBuild the key listener, then electron-forge make --arch=arm64.
  4. 04Publish the DMGThe produced .dmg from out/make is attached to the GitHub release.
The landing page's Download button points at the latest release's VoiceFlow.dmg, so tagging a release is all it takes to ship an update to users.