Ship It: Building and Distribution
Ship It: Building and Distribution
Section titled “Ship It: Building and Distribution”Congratulations! You have set up your environment, built a beautiful frontend, connected it to a robust Rust backend, and polished your app with native features. Now, it is time to take your creation out of the development laboratory and ship it to the world. In this chapter, we will transform your source code into optimized, installable binaries.
The Build Command
Section titled “The Build Command”During development, we used tauri dev. This command focuses on hot-reloading and quick feedback loops. However, the binaries it produces are unoptimized and contain debug symbols, making them large and slow. To create a production-ready application, we use the build command.
Before you run it, you must ensure your application has a unique identifier in tauri.conf.json. If you are still using com.tauri.dev, the build will fail. Change it to something unique, like com.yourname.appname.
{ "identifier": "com.mycompany.awesomeapp", ...}Once configured, run the following command in your terminal:
# If using npmnpm run tauri build
# If using cargo directlycargo tauri buildThis command performs a sequence of critical tasks:
- It runs your frontend build script (e.g.,
npm run build) to generate the HTML/CSS/JS assets. - It compiles the Rust code with the
--releaseflag, enabling aggressive optimizations. - It bundles the frontend assets directly into the Rust binary.
- It generates platform-specific installers (MSI, DMG, DEB, etc.).
Code Signing
Section titled “Code Signing”Operating systems are protective gatekeepers. If you try to run an application that hasn’t been “vouched for,” the OS will warn the user or block the app entirely. This is where code signing comes in. It is like a digital wax seal that proves the app comes from you and hasn’t been tampered with.
- macOS: This is the strictest platform. To distribute an app without users seeing a “Damaged and can’t be opened” error, you must sign the app and Notarize it with Apple. This requires an Apple Developer Program membership. Tauri needs your certificate and specific environment variables (like
APPLE_CERTIFICATEandAPPLE_PASSWORD) to automate this during the build process. - Windows: While you can distribute unsigned apps, users will likely see the scary “Windows protected your PC” SmartScreen warning. To avoid this, you need an EV (Extended Validation) or OV code signing certificate. You configure the certificate path and password in your
tauri.conf.jsonor environment variables. - Linux: Generally relies on distribution maintainers or formats like AppImage, which don’t strictly enforce code signing in the same way, though signing GPG keys for repositories is common practice.
Generating Installers
Section titled “Generating Installers”Tauri is smart enough to generate the appropriate installer for the machine you are building on. You can configure which formats to output in the bundle section of your configuration.
{ "bundle": { "active": true, "targets": "all", // or specific targets like ["msi", "nsis"] ... }}Here is what you generally produce for each platform:
| Platform | Format | Description |
|---|---|---|
| Windows | .msi / .exe | The .msi is a standard Windows Installer. Tauri also supports NSIS (.exe), which is often preferred for a lighter, more custom installation experience. |
| macOS | .dmg / .app | The .app is the executable bundle, while the .dmg (Disk Image) is the standard container used for distribution. |
| Linux | .deb / .AppImage | .deb is for Debian/Ubuntu based systems. .AppImage is a portable format that runs on most Linux distributions without installation. |
| Android | .apk / .aab | APK is for direct installation; AAB (Android App Bundle) is required for uploading to the Google Play Store. |
Automating with GitHub Actions
Section titled “Automating with GitHub Actions”Building manually on your local machine is fine for testing, but for a real release, you want consistency. Furthermore, you usually cannot build a macOS app on Windows or vice versa due to the platform-specific WebView bindings. The solution is Continuous Integration (CI).
Tauri provides an official GitHub Action that automates the build and release process. By setting up a workflow file, GitHub will spin up virtual machines (Windows, macOS, and Ubuntu), build your app on all of them simultaneously, and upload the installers to a GitHub Release.
Here is a simplified example of a .github/workflows/release.yml file:
name: Releaseon: push: tags: - 'v*'
jobs: release: strategy: fail-fast: false matrix: platform: [macos-latest, ubuntu-22.04, windows-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 - name: setup node uses: actions/setup-node@v4 with: node-version: 20 - name: install Rust stable uses: dtolnay/rust-toolchain@stable
# Install dependencies (Linux only) needs specific steps here...
- name: Build the app uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tagName: ${{ github.ref_name }} releaseName: 'App v__VERSION__' releaseBody: 'See the assets to download this version and install.' releaseDraft: true prerelease: falseWith this setup, simply pushing a tag like v1.0.0 to your repository will trigger the cloud builders. Minutes later, your GitHub Releases page will be populated with professional installers for every major operating system, ready for your users to download.