Packaging
Bundle installers for Windows, macOS, and Linux with Tauri.
Desktop deployment means shipping installers and, if updates are enabled,
hosting a signed update feed—not deploying a web app. Tauri's bundle settings
live in src-tauri/tauri.conf.json; the macOS window override is in
src-tauri/tauri.macos.conf.json.
Build a release
pnpm tauri build # compile and create this platform's installers
pnpm tauri build --no-bundle # compile the release app without installersBoth take minutes because they build the frontend and Rust binary. Use
--no-bundle at meaningful milestones, then run the full command on each
platform you ship. Artifacts are written below src-tauri/target/release/bundle/.
Build platform installers on their corresponding OS or in matching CI runners.
The root config supplies the product name, version, reverse-DNS identifier,
default frameless window, bundle publisher, homepage, icon list, and
createUpdaterArtifacts: true. It requests NSIS, MSI, DMG, AppImage, deb, and
rpm targets; each runner produces the targets it supports.
Windows creates NSIS and MSI bundles. NSIS installs for the current user, uses LZMA compression, and lets Tauri download the WebView2 bootstrapper when needed. The config prevents downgrades and uses SHA-256 timestamps.
macOS creates a DMG. The bundle requires macOS 11 or later and enables the hardened runtime. The macOS override switches the main window to an overlay titlebar while preserving the app's custom controls.
Linux produces AppImage, deb, and rpm formats. AppImage is the only one the built-in updater can update; deb and rpm users update through their package manager or a new manual download.
Signing and notarization
Local and forked builds remain useful without credentials: unset signing
variables result in unsigned output. For distribution, keep these values in CI
secrets, never in .env or the repository.
| Platform | Credentials | Distribution note |
|---|---|---|
| Windows | WINDOWS_CERTIFICATE, WINDOWS_CERTIFICATE_PASSWORD | Signing identifies the publisher; a new app can still receive SmartScreen warnings until it earns reputation. |
| macOS | APPLE_ID, APPLE_PASSWORD, APPLE_TEAM_ID, APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY | Sign and notarize release builds. Unsigned downloads can be blocked or reported as damaged by Gatekeeper. |
| Linux | None by default | Linux packages are conventionally unsigned. |
Updater signing is separate from platform code signing: release builds also
need TAURI_SIGNING_PRIVATE_KEY and, when protected,
TAURI_SIGNING_PRIVATE_KEY_PASSWORD. The public verification key belongs in
tauri.conf.json; the private key never does. See Auto-Update.
Icons
Generate the application icon set from a square PNG (1024×1024 is recommended):
pnpm tauri icon path/to/icon.pngThis regenerates src-tauri/icons/, including .icns, .ico, Linux PNGs, and
Windows tile assets. Tray art is separate: update the source mark and its
derived resources/build/tray/ PNGs as described in docs/APP_ICONS.md, then
verify the dock/taskbar, installer, and tray icons in a real build.
Verify before shipping
Run the template's full quality gate:
pnpm format:check && pnpm lint:check && pnpm typecheck && pnpm test:unit
cargo fmt --check --manifest-path src-tauri/Cargo.toml
cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
cargo test --manifest-path src-tauri/Cargo.toml.github/workflows/ci.yml runs that gate across Linux, macOS, and Windows,
checks generated Specta binding drift, and performs pnpm tauri build --no-bundle.
The separate WebdriverIO + tauri-driver smoke harness in test/e2e/ has its
own package.json: it runs on Linux and Windows, has no macOS backend, and CI
runs it on pushes to main rather than as the PR gate.
