# How Tauri's Bundler Works and What Package Formats It Supports: A Complete Guide

> Discover how Tauri's bundler creates native installers for various formats including .app, .dmg, .deb, and .msi. Learn about its Rust-based process and supported package types.

- Repository: [Tauri/tauri](https://github.com/tauri-apps/tauri)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Tauri's bundler (`tauri-bundler`) is a Rust library that transforms compiled binaries into native installers by patching the binary with bundle-type markers, optionally signing it, and dispatching to platform-specific modules that generate `.app`, `.dmg`, `.deb`, `.rpm`, `.msi`, `.exe` (NSIS), and `.AppImage` packages.**

The `tauri-bundler` crate in the `tauri-apps/tauri` repository serves as the final packaging engine in the Tauri build pipeline. It consumes the binary produced by `tauri build` and orchestrates the creation of platform-native distributables through a series of deterministic steps. Understanding how this Tauri bundler operates enables developers to debug packaging failures and optimize their distribution configuration.

## The Bundling Pipeline: From Binary to Installer

The bundler follows a strict seven-step pipeline defined in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs). Each step transforms the artifact until it becomes a shippable package.

### Step 1: Load Configuration

The process begins in [`src/bundle/settings.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/settings.rs) where the `SettingsBuilder` parses [`tauri.conf.json`](https://github.com/tauri-apps/tauri/blob/main/tauri.conf.json) and produces a `Settings` struct. This struct contains critical metadata including `package_types`, signing certificates, and platform-specific overrides.

### Step 2: Resolve Package Types

The bundler calls `settings.package_types()` (lines 94-100 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)) to retrieve a vector of `PackageType` enum values. These determine which platform modules will execute during the build.

### Step 3: Patch Binary with Bundle Markers

Before packaging, the bundler modifies the compiled binary via `patch_binary` (lines 22-62 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)). It injects platform-specific tokens like `__TAURI_BUNDLE_TYPE_VAR_*` into the binary. These markers allow Tauri's updater to identify the package format at runtime when checking for updates.

### Step 4: Sign the Binary

If code signing is configured, the bundler invokes `sign_binaries_if_needed` (lines 8-12 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)). On Windows, this calls `windows::sign::try_sign` immediately after patching. macOS signing occurs later within the platform-specific module using the `codesign` command.

### Step 5: Dispatch to Platform Bundlers

The core orchestration logic matches each `PackageType` to its implementation (lines 46-78 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)):

```rust
match package_type {
    PackageType::MacOsBundle => macos::app::bundle_project(&settings)?,
    PackageType::Nsis => windows::nsis::bundle_project(&settings, &_updater)?,
    // ... additional variants
}

```

### Step 6: Collect Artifacts

Each platform module returns paths to generated files. The bundler wraps these in a `Bundle` struct containing the `package_type` and a list of `PathBuf` objects (lines 81-84 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)), which are ultimately returned to the CLI for logging.

### Step 7: Generate Updater Bundle

When `settings.updater()` returns true, the bundler creates a supplementary updater bundle (lines 95-100 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)). This lightweight package contains only the updater binary and manifest, enabling Tauri's auto-update mechanism to replace the main application later.

## Supported Package Formats

The `PackageType` enum in [`src/bundle/settings.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/settings.rs) defines all supported output formats. The bundler organizes these by target operating system.

### macOS Formats

- **`MacOsBundle`** — Generates a `.app` bundle via [`src/bundle/macos/app.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/macos/app.rs). This includes copying resources, embedding entitlements, and code signing.
- **`Dmg`** — Creates a disk image (`.dmg`) using [`src/bundle/macos/dmg/mod.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/macos/dmg/mod.rs), which leverages AppleScript to arrange the window layout and compress the `.app` bundle.
- **`IosBundle`** — Produces an iOS application package (`.ipa`) through [`src/bundle/macos/ios.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/macos/ios.rs) for mobile deployment targets.

### Linux Formats

- **`AppImage`** — Builds a standalone executable (`.AppImage`) via [`src/bundle/linux/appimage/mod.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/linux/appimage/mod.rs), which bundles the application and its dependencies into a single file using the AppImage toolchain.
- **`Deb`** — Packages a Debian installer (`.deb`) using [`src/bundle/linux/debian.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/linux/debian.rs) by invoking `dpkg-deb` to construct the control archive and data tarball.
- **`Rpm`** — Generates an RPM package (`.rpm`) through [`src/bundle/linux/rpm.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/linux/rpm.rs) by driving `rpmbuild` with a generated spec file.

### Windows Formats

- **`Nsis`** — Creates an installer executable (`.exe`) via [`src/bundle/windows/nsis/mod.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/windows/nsis/mod.rs). This module downloads the NSIS toolchain, renders an `.nsi` template using Handlebars, and executes `makensis` to produce the installer.
- **`WindowsMsi`** — Generates a Microsoft Installer (`.msi`) through [`src/bundle/windows/msi/mod.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/windows/msi/mod.rs), which automates the WiX Toolset to compile XML definitions into installable packages.

## High-Level Architecture

The bundler's codebase separates concerns into four distinct layers:

**Configuration Layer** — The `SettingsBuilder` aggregates per-platform sections from [`tauri.conf.json`](https://github.com/tauri-apps/tauri/blob/main/tauri.conf.json) (e.g., `bundler > windows`, `bundler > macos`) into a unified `Settings` instance.

**Core Engine** — The `bundle_project(settings)` function in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs) coordinates the entire workflow, handling target resolution, binary patching, and dispatch logic.

**Platform Modules** — Each operating system has dedicated sub-modules:
- **macOS**: Handles resource copying, plist generation, entitlements, and DMG creation via AppleScript.
- **Linux**: Invokes external tools (`appimagetool`, `dpkg-deb`, `rpmbuild`) to construct distribution-specific packages.
- **Windows**: Manages NSIS template rendering and WiX compilation for MSI generation.

**Updater Support** — When enabled, [`src/bundle/updater_bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle/updater_bundle.rs) generates a minimal bundle containing only the updater agent and version manifest, separate from the main application package.

## Configuration and Usage

The CLI automatically invokes the bundler when you run build commands:

```bash

# Build and bundle for the current host platform

tauri build

# Cross-compile for Linux with specific package formats

tauri build --targets x86_64-unknown-linux-gnu \
    --bundles appimage,deb,rpm

# Build only the NSIS installer on Windows

tauri build --bundle nsis

```

Under the hood, these commands call `tauri_bundler::bundle_project(&settings)`, passing the configuration parsed from your project root. The bundler returns a list of artifact paths that the CLI prints to stdout.

## Summary

- **Tauri's bundler** is a Rust library located in `crates/tauri-bundler` that converts binaries into native installers.
- The **seven-step pipeline** includes configuration loading, package type resolution, binary patching with `__TAURI_BUNDLE_TYPE_VAR_*` markers, optional signing, platform dispatch, artifact collection, and updater bundle generation.
- **Supported formats** include `.app` and `.dmg` for macOS, `.deb`, `.rpm`, and `.AppImage` for Linux, and `.msi` and `.exe` (NSIS) for Windows.
- **Code signing** occurs at different stages: immediately after patching on Windows via `windows::sign::try_sign`, and during platform bundling on macOS via `codesign`.
- The **updater bundle** (generated when `updater.enabled = true`) is a separate lightweight artifact that enables Tauri's self-update capability.

## Frequently Asked Questions

### What file formats can Tauri's bundler create?

The bundler supports nine distinct package types defined in the `PackageType` enum: `MacOsBundle` (`.app`), `Dmg` (`.dmg`), `IosBundle` (`.ipa`), `AppImage` (`.AppImage`), `Deb` (`.deb`), `Rpm` (`.rpm`), `Nsis` (`.exe` installer), and `WindowsMsi` (`.msi`). Each format has a dedicated module in `src/bundle/` that handles the specific packaging requirements for that platform.

### How does the Tauri bundler handle code signing?

On Windows, the bundler calls `windows::sign::try_sign` immediately after patching the binary in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs). On macOS, signing occurs within the platform module ([`macos/app.rs`](https://github.com/tauri-apps/tauri/blob/main/macos/app.rs)) using the native `codesign` command after the `.app` bundle structure is assembled. Linux packages typically do not include embedded signatures, though users can add GPG signing hooks for `.deb` and `.rpm` files through custom configuration.

### Can I build macOS bundles on Linux or Windows?

Yes, the bundler is designed to be cross-platform. You can build macOS `.app` bundles and `.dmg` files on Linux by using cross-compilation toolchains like `cargo-xwin` for Windows targets or appropriate macOS SDKs. However, **code signing** and **notarization** for macOS require running on macOS hardware or using remote signing services, as they depend on Apple's proprietary tools.

### What is the purpose of the binary patching step in Tauri bundling?

The `patch_binary` function (lines 22-62 in [`src/bundle.rs`](https://github.com/tauri-apps/tauri/blob/main/src/bundle.rs)) injects marker tokens (`__TAURI_BUNDLE_TYPE_VAR_*`) into the compiled binary. These markers identify the package type (e.g., NSIS, DMG, AppImage) at runtime. When Tauri's updater checks for new versions, it reads these markers to determine which update artifact to download and install, ensuring the correct package format is used for the current installation.