Windows
How to package a Tauri v2 application for Windows using MSI and NSIS installers, configure WebView2 installation, handle code signing, and prepare for distribution.
Tauri produces two main installer formats for Windows: an MSI package built with WiX Toolset v3, and an NSIS-based setup executable. Both are generated when you run tauri build on a Windows machine. This document covers how to configure, produce, and understand each installer, along with the platform-specific options that matter for distribution — WebView2 deployment, code signing, and Microsoft Store compatibility.
What Windows Packaging Means
When you run npm run tauri build, the Tauri CLI compiles your Rust backend into a native Windows executable and bundles your frontend into it. That executable (yourapp.exe) can run on its own, but shipping it directly to users creates friction: they have to trust an unsigned binary, manually place it somewhere, and the app can't integrate with system install/uninstall mechanisms. Packaging solves this by wrapping the executable inside an installer that handles placement, shortcuts, registry entries, and uninstallation.
Tauri's bundler generates two artifacts by default:
yourapp_x64.msi— a Microsoft Installer package built with WiX.yourapp_x64-setup.exe— an NSIS installer that can also act as a self-extracting setup.
Both contain the same application files; the difference is how they install and the Windows features they support.
MSI vs NSIS at a glance:
MSI installers are preferred in enterprise environments because they integrate with Group Policy, silent deployment, and centralized management tools. NSIS installers give you more visual customization (wizard pages, branding) and are easier to cross-compile from Linux or macOS. You can ship both; many Tauri projects do.
Prerequisites for Building on Windows
Before you can produce a Windows installer, your development machine needs the toolchain for that target. If you are building directly on Windows, the only extra requirement beyond the standard Tauri setup is the WiX Toolset — MSI generation depends on it.
The standard Tauri Windows prerequisites already include:
- Microsoft C++ Build Tools (with the "Desktop development with C++" workload)
- WebView2 Evergreen Bootstrapper (for runtime, not required for building but needed for testing)
- Rust with the
stable-x86_64-pc-windows-msvctoolchain
For WiX, install WiX Toolset v3. You can get it from the WiX releases page. Tauri’s bundler invokes light.exe, candle.exe, and other WiX tools automatically, so they need to be on your PATH.
Missing WiX produces only the NSIS installer:
If WiX is not installed or not found on your PATH, tauri build will still succeed but will only produce the NSIS .exe installer. The MSI will be skipped without an error — check the build output to confirm both were generated.
How tauri build Works on Windows
The build command goes through a sequence specific to Windows packaging. Understanding this order helps when something fails.
Rust compilation
The CLI first compiles your Rust backend for the target triple x86_64-pc-windows-msvc (or whichever target you specify with --target). This produces src-tauri/target/release/yourapp.exe.
Frontend build
The beforeBuildCommand from tauri.conf.json runs — typically npm run build — to produce your React/Vite output in the frontendDist directory.
Resource bundling
The Tauri bundler copies the frontend files and any configured resources into a folder beside the Rust executable. By default this goes to src-tauri/target/release/bundle/.
MSI generation (WiX)
If WiX is available, Tauri generates a .wxs source file and compiles it into a .msi package. This embeds your app, defines installation directories, and registers an uninstaller entry.
NSIS installer generation
Tauri creates an NSIS script and invokes makensis to produce the -setup.exe file. This wraps the same app folder into a customizable installer with a wizard UI.
The output lands in src-tauri/target/release/bundle/msi/ and src-tauri/target/release/bundle/nsis/. Both are ready to distribute.
MSI Installer – WiX Toolset
MSI is the native installation format for Windows. It's a database-driven system where installation is a transaction: either everything succeeds, or the system rolls back. That reliability, plus built-in support for silent installs, repair, and removal, makes MSI the standard in corporate environments.
Tauri generates an MSI that:
- Installs your app to
%ProgramFiles%\YourAppName\ - Creates a Start Menu shortcut
- Registers an uninstall entry in Add/Remove Programs
- Prompts for elevation (MSI installers run as administrator by default)
You don't write WiX source files yourself — Tauri generates them from your configuration. However, you can customize certain aspects through tauri.conf.json.
MSI only works when built on Windows:
WiX tools can only run on Windows. If you need an MSI and your development machine is macOS or Linux, you must build on a Windows CI runner (like GitHub Actions) or a local VM. There is no cross-compilation path for MSI.
Configuring the MSI Installer
The relevant configuration lives under bundle.windows.wix in tauri.conf.json. Here is a realistic setup that customizes the installer language, adds a license file, and sets the application GUID:
{
"bundle": {
"active": true,
"targets": ["msi", "nsis"],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.ico"
],
"windows": {
"wix": {
"language": "en-US",
"template": "main.wxs",
"fragmentPaths": ["./installer/custom.wxs"],
"bannerPath": "./installer/banner.bmp",
"dialogImagePath": "./installer/dialog.bmp",
"license": "./installer/license.rtf"
}
}
}
}
The license field expects an RTF file, not plain text. If you provide a .txt file, WiX will reject it. This trips up beginners often because the WiX documentation requires RTF formatting, and Tauri passes the file path directly to the WiX compiler.
A minimal license RTF looks like this — you can generate one from WordPad or any word processor:
{\rtf1\ansi\deff0
Copyright (c) 2025 Your Company. All rights reserved.\par
}
The fragmentPaths array lets you inject custom WiX XML fragments. For example, to add a registry key:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroupRef Id="YourAppAdditionalComponents" />
</Fragment>
</Wix>
If you need fine-grained control over the installer, you can supply a full template file and bypass Tauri's automatic generation entirely. The template mechanism is an escape hatch for complex requirements — most applications won't need it.
NSIS Installer
NSIS (Nullsoft Scriptable Install System) is a lightweight, script-driven installer framework. Tauri uses it to produce the -setup.exe file. NSIS installers are self-contained, have a lower overhead than MSI, and can be built on any platform — including Linux and macOS for cross-compilation.
The NSIS installer that Tauri generates:
- Shows a wizard with a license page, install directory chooser, and progress bar
- Offers a choice between per-user and per-machine installation
- Creates Start Menu shortcuts
- Registers an uninstaller
- Supports silent installs via
/Sflag
NSIS is cross-platform friendly:
If you need to produce a Windows installer from a Linux CI server, NSIS is your only option. The combination of cargo-xwin for the Rust binary and NSIS for the installer allows fully automated Windows builds without touching a Windows machine.
Customizing the NSIS Installer
NSIS customization is done through bundle.windows.nsis in tauri.conf.json. The most common tweaks are the header image, installer icon, and install mode.
{
"bundle": {
"windows": {
"nsis": {
"installMode": "currentUser",
"installerIcon": "icons/installer.ico",
"headerImage": "installer/header.bmp",
"sidebarImage": "installer/sidebar.bmp",
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "My App",
"license": "installer/license.txt"
}
}
}
}
installMode can be "currentUser", "perMachine", or "both". Choosing "currentUser" avoids the elevation prompt, which is often the right call for apps that don't need system-wide access. "perMachine" requires administrator privileges but makes the app available to all users on the computer.
Never ship an unsigned NSIS installer to the public internet:
An unsigned .exe downloaded from the web triggers SmartScreen warnings and makes Windows Defender suspicious. Users see red banners saying "Windows protected your PC." Code signing is not optional for distribution — it's the minimum bar for trust. The Code Signing section covers this in detail.
WebView2 Installation Options
Tauri relies on Microsoft Edge WebView2 to render the web frontend. If a user's system doesn't have WebView2 installed, your app won't start. The Windows installer can handle this for you — Tauri offers five strategies for deploying WebView2 alongside your app.
These strategies are set via bundle.windows.webviewInstallMode in tauri.conf.json. The choice impacts installer size, offline compatibility, and Windows 7 support.
{
"bundle": {
"windows": {
"webviewInstallMode": {
"type": "downloadBootstrapper"
}
}
}
}
Each type works as follows:
type | Internet Required | Size Added | Notes |
|---|---|---|---|
downloadBootstrapper | Yes | 0 MB | Default. Downloads the bootstrapper at install time. Small installer, needs connectivity. |
embedBootstrapper | Yes | ~1.8 MB | Embeds the bootstrapper; still downloads the actual runtime. Better for Windows 7 MSI targets. |
offlineInstaller | No | ~127 MB | Bundles the full WebView2 standalone installer. Best for offline environments. |
fixedVersion | No | ~180 MB | Ships a specific, fixed version of WebView2 with your app. Maximum control, largest size. |
skip | No | 0 MB | Does nothing about WebView2. Use only if you guarantee the runtime is preinstalled. |
For most public-facing apps, downloadBootstrapper is a good default. The installer itself stays small, and the bootstrapper fetches the latest WebView2 from Microsoft's servers. If your users are often offline or behind restrictive corporate proxies, switch to offlineInstaller despite the size increase.
skip mode can break your app silently:
If you set webviewInstallMode to "skip" and the user's machine lacks WebView2, your app will crash on launch with an opaque error. Only use this when you control the target environment (e.g., an enterprise fleet where WebView2 is deployed via IT policy) and you've verified it's present.
Code Signing on Windows
Windows uses Authenticode code signing to establish the publisher identity of executables and installers. An unsigned app will be blocked by SmartScreen, flagged by antivirus, and treated as untrusted by Windows. For distribution beyond a handful of test machines, code signing is a hard requirement.
Tauri supports code signing for both the MSI and NSIS installers through environment variables or configuration. The preferred setup uses environment variables because they keep secrets out of your config file.
How Windows Code Signing Works
The signing process attaches a digital signature to the .msi and .exe files. This signature is created with a code signing certificate — either an Extended Validation (EV) certificate on a hardware token, or a standard certificate stored as a .pfx file. When the user runs the installer, Windows checks the signature against the publisher's certificate and validates the chain up to a trusted root.
For MSI, Tauri signs the .msi directly. For NSIS, it signs the uninstaller binary embedded inside the setup executable.
Configuration via Environment Variables
Set these variables before running tauri build:
| Variable | Purpose |
|---|---|
TAURI_SIGNING_PRIVATE_KEY | Path to the .pfx file or a base64-encoded string of it. |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD | Password for the .pfx file. |
Tauri will automatically detect these and sign the output. For CI environments, it's safer to store the certificate as a base64-encoded secret and decode it at build time.
$env:TAURI_SIGNING_PRIVATE_KEY = "C:\secrets\certificate.pfx"
$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = "your-password"
npm run tauri build
If you use Azure Key Vault or a similar HSM-backed signing service, you'll need to integrate signtool externally — Tauri's built-in signing doesn't directly support remote signing. In that workflow, build first with signing disabled, then sign the resulting files yourself.
Obtaining a Code Signing Certificate
You need a certificate from a Certificate Authority (CA) in the Microsoft Trusted Root Program. Standard options include:
- Azure Artifact Signing — Microsoft's managed code signing service. No hardware token needed, pay-per-signing.
- DigiCert, Sectigo, GlobalSign — Traditional CAs. EV certificates come with a USB token for two-factor security.
If you're publishing through the Microsoft Store and submitting an MSI/EXE, the Store has its own signing requirements. For MSIX submissions, Microsoft re-signs your package, so you don't need your own certificate for Store distribution via that path.
Self-signed certificates only work in controlled environments:
A self-signed certificate will sign your installer, but Windows won't trust it unless the certificate is deployed to the Trusted Publishers store on every target machine — which is possible in enterprise environments via Group Policy, but impossible for public distribution.
The MSI/EXE Duality and Standalone Executables
It's worth clarifying: the .exe you find in src-tauri/target/release/yourapp.exe is not an installer. It's the actual application binary. You can run it directly, and it will launch your Tauri app without any installation step. This is useful during development and for quick testing, but it's not a distribution format for end users. The app won't appear in Start Menu, won't have an uninstaller, and Windows will still flag it if unsigned.
When you run the NSIS -setup.exe, it extracts that application executable and supporting files into a folder the user chooses, then creates shortcuts. The MSI does the same through Windows Installer.
For portable deployment — a single .exe that users can carry on a USB stick — you'd need to self-extract and self-configure. Tauri does not provide an official portable packaging mode, but you can achieve it by zipping the application folder and documenting that users can run the executable directly.
Cross-Compiling for Windows from Linux or macOS
If your development machine doesn't run Windows, you can still produce the NSIS installer. The MSI will not be available unless you use a Windows VM or CI. Cross-compilation requires setting up the Windows Rust target, a linker that understands PE format, and the NSIS toolchain.
Install the Windows Rust target
rustup target add x86_64-pc-windows-msvc
Install LLVM and LLD linker
The default Microsoft linker doesn't run on other platforms. Use LLD instead. On Ubuntu:
sudo apt install lld llvm
On macOS with Homebrew:
brew install llvm
# Add /opt/homebrew/opt/llvm/bin to PATH
Install cargo-xwin
cargo-xwin fetches the Windows SDKs and sets up the cross-compilation environment transparently.
cargo install --locked cargo-xwin
Install NSIS
On Ubuntu:
sudo apt install nsis
On macOS:
brew install nsis
Some distros package NSIS without plugins. If makensis complains about missing plugins, download the full NSIS zip from the official releases and copy the Plugins and Stubs directories into the NSIS installation path.
Build with the cross-target
Pass --runner cargo-xwin and the target:
npm run tauri build -- --runner cargo-xwin --target x86_64-pc-windows-msvc
The output will be in target/x86_64-pc-windows-msvc/release/bundle/nsis/.
Microsoft Store Distribution and WACK
Packaging for the Microsoft Store adds an extra layer. If you intend to distribute via the Store, you'll need to produce an MSIX package or submit an MSI/EXE through the Store's ingestion pipeline. Either way, the app must pass the Windows App Certification Kit (WACK).
Tauri v2 apps have been known to fail WACK's "Package Sanity Test" due to references to kernel32.dll!CreateProcessW, shell32.dll!ShellExecuteW, and cmd.exe. These are internal calls made by WebView2 and the Tauri runtime — they are not removable from the app level. As of Tauri v2, there is no configuration switch to strip these dependencies, and the maintainers have acknowledged this can cause Store rejection for Windows S Mode compatibility.
Windows S Mode may block your app:
If your target audience includes Windows 10/11 in S Mode, the WACK test failure is a hard blocker. At the time of writing, there is no official workaround from Tauri aside from requesting a Store exception. If S Mode support is critical, test your app with WACK early in your release cycle to gauge feasibility.
For Store submissions outside S Mode, the MSI/EXE path is still viable. The Store requires the installer to be signed with a certificate from a CA in the Microsoft Trusted Root Program. Once accepted, you manage updates through your own mechanism — the Store won't auto-update MSI/EXE submissions.
MSIX avoids the installer trust problem:
If you package your app as MSIX and submit it that way, Microsoft re-signs the package and manages updates for you. The WACK failure may still apply, but the signing and distribution burden is lower. Tauri does not natively produce MSIX — you would use the Microsoft MSIX Packaging Tool on the output folder, which is an additional step.
Configuring for ARM64 and 32-bit Targets
By default, Tauri builds for the architecture of the machine running the build — usually x86_64. If you need to support older 32-bit Windows systems or modern ARM64 devices (like Surface Pro X), you must explicitly target those architectures.
First, install the appropriate Rust targets:
rustup target add i686-pc-windows-msvc
rustup target add aarch64-pc-windows-msvc
For ARM64, you also need the C++ ARM64 build tools from Visual Studio Installer. In the "Individual Components" tab, check "C++ ARM64 build tools". Then build with the --target flag:
npm run tauri build -- --target aarch64-pc-windows-msvc
The installer produced will be architecture-specific. You cannot ship a single installer that handles multiple architectures — you'll distribute separate installers for x64, ARM64, and x86, or provide a single NSIS installer that detects the architecture and extracts the appropriate binary (requires custom NSIS scripting beyond the default Tauri generation).
Common Mistakes and Troubleshooting
light.exe not found. This means WiX is not installed or not on PATH. The build will skip MSI silently. Install WiX Toolset v3 and ensure light.exe and candle.exe are accessible from the terminal where you run tauri build.
MSI fails with "Failed to run light.exe". Check if VBSCRIPT is enabled on your Windows machine. WiX uses VBScript internally, and some systems (especially hardened enterprise images) disable it. You can re-enable it via Settings → Apps → Optional features → More Windows features.
SmartScreen blocks the installer even though it's signed. A signature alone doesn't grant reputation. SmartScreen builds reputation over time based on the number of downloads and the certificate's history. New certificates and low-download apps will see a warning until enough users install the app. There's no way to skip this phase except by submitting to the Microsoft Store.
"Windows protected your PC" for an unsigned installer. This is the expected behavior. The only fix is code signing. For internal testing, you can right-click → Properties → "Unblock" on the downloaded file, but that does not scale beyond personal use.
Don't forget the icon.ico for Windows:
Tauri's Windows installer uses icon.ico for the app icon, not the PNG icons used on other platforms. If you don't provide a valid .ico file, the installer and the installed executable will show a generic icon. Ensure you have at least 256x256 and 48x48 resolutions inside the .ico.
Summary
Packaging for Windows means producing an MSI, an NSIS installer, or both — each suited to different distribution channels. The MSI serves enterprise needs with silent installs and Group Policy integration, but requires a Windows build machine and WiX. The NSIS installer is more flexible, cross-compilable, and often preferred for direct downloads. Regardless of which you ship, code signing is not a nice-to-have; it's the requirement for your app to be taken seriously by Windows security layers.
WebView2 installation mode is another knob that directly impacts user experience — choose downloadBootstrapper for typical online users, offlineInstaller for air-gapped environments, and never use skip unless you fully control the target machines. If Microsoft Store distribution is on your roadmap, test with WACK early, especially if Windows S Mode matters to your audience.