| name | distributing-tauri-for-macos |
| description | Guides users through distributing Tauri applications on macOS, including creating DMG installers, configuring app bundles, setting up entitlements, and customizing Info.plist files for proper macOS distribution. |
Tauri macOS Distribution
This skill covers distributing Tauri v2 applications on macOS, including DMG installers and application bundle configuration.
Overview
macOS distribution for Tauri apps involves two primary formats:
- Application Bundle (.app) - The executable directory containing all app components
- DMG Installer (.dmg) - A disk image that wraps the app bundle for easy drag-and-drop installation
Building for macOS
Build Commands
Generate specific bundle types using the Tauri CLI:
npm run tauri build -- --bundles app
yarn tauri build --bundles app
pnpm tauri build --bundles app
cargo tauri build --bundles app
npm run tauri build -- --bundles dmg
yarn tauri build --bundles dmg
pnpm tauri build --bundles dmg
cargo tauri build --bundles dmg
npm run tauri build -- --bundles app,dmg
Application Bundle Structure
The .app directory follows macOS conventions:
<productName>.app/
Contents/
Info.plist # App metadata and configuration
MacOS/
<app-name> # Main executable
Resources/
icon.icns # App icon
[bundled resources] # Additional resources
_CodeSignature/ # Code signature files
Frameworks/ # Bundled frameworks
PlugIns/ # App plugins
SharedSupport/ # Support files
DMG Installer Configuration
Configure DMG appearance in tauri.conf.json:
Complete DMG Configuration Example
{
"bundle": {
"macOS": {
"dmg": {
"background": "./images/dmg-background.png",
"windowSize": {
"width": 660,
"height": 400
},
"windowPosition": {
"x": 400,
"y": 400
},
"appPosition": {
"x": 180,
"y": 220
},
"applicationFolderPosition": {
"x": 480,
"y": 220
}
}
}
}
}
DMG Configuration Options
| Option | Type | Default | Description |
|---|
background | string | - | Path to background image relative to src-tauri |
windowSize.width | number | 660 | DMG window width in pixels |
windowSize.height | number | 400 | DMG window height in pixels |
windowPosition.x | number | - | Initial window X position on screen |
windowPosition.y | number | - | Initial window Y position on screen |
appPosition.x | number | 180 | App icon X position in window |
appPosition.y | number | 220 | App icon Y position in window |
applicationFolderPosition.x | number | 480 | Applications folder X position |
applicationFolderPosition.y | number | 480 | Applications folder Y position |
Note: Icon sizes and positions may not apply correctly when building on CI/CD platforms due to a known issue with headless environments.
Info.plist Customization
Creating a Custom Info.plist
Create src-tauri/Info.plist to extend the default configuration. The Tauri CLI automatically merges this with generated values.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>This app requires camera access for video calls</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access for audio recording</string>
<key>NSLocationUsageDescription</key>
<string>This app requires location access for mapping features</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to import images</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>My Document</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>mydoc</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.example.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
</dict>
</plist>
Common Info.plist Keys
| Key | Description |
|---|
NSCameraUsageDescription | Camera access explanation |
NSMicrophoneUsageDescription | Microphone access explanation |
NSLocationUsageDescription | Location access explanation |
NSPhotoLibraryUsageDescription | Photo library access explanation |
NSAppleEventsUsageDescription | AppleScript/automation access |
CFBundleDocumentTypes | Supported document types |
CFBundleURLTypes | Custom URL schemes |
LSMinimumSystemVersion | Minimum macOS version (prefer tauri.conf.json) |
Info.plist Localization
Support multiple languages with localized strings:
Directory structure:
src-tauri/
infoplist/
en.lproj/
InfoPlist.strings
de.lproj/
InfoPlist.strings
fr.lproj/
InfoPlist.strings
es.lproj/
InfoPlist.strings
Example InfoPlist.strings (German):
"NSCameraUsageDescription" = "Diese App benötigt Kamerazugriff für Videoanrufe";
"NSMicrophoneUsageDescription" = "Diese App benötigt Mikrofonzugriff für Audioaufnahmen";
Configure in tauri.conf.json:
{
"bundle": {
"resources": {
"infoplist/**": "./"
}
}
}
Entitlements Configuration
Entitlements grant special capabilities when your app is code-signed.
Creating Entitlements.plist
Create src-tauri/Entitlements.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.microphone</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>
Configure Entitlements in tauri.conf.json
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist"
}
}
}
Common Entitlements Reference
Sandbox Entitlements:
| Entitlement | Description |
|---|
com.apple.security.app-sandbox | Enable app sandbox (required for App Store) |
com.apple.security.network.client | Outbound network connections |
com.apple.security.network.server | Incoming network connections |
com.apple.security.files.user-selected.read-write | Access user-selected files |
com.apple.security.files.downloads.read-write | Access Downloads folder |
Hardware Entitlements:
| Entitlement | Description |
|---|
com.apple.security.device.camera | Camera access |
com.apple.security.device.microphone | Microphone access |
com.apple.security.device.usb | USB device access |
com.apple.security.device.bluetooth | Bluetooth access |
Hardened Runtime Entitlements:
| Entitlement | Description |
|---|
com.apple.security.cs.allow-jit | Allow JIT compilation |
com.apple.security.cs.allow-unsigned-executable-memory | Allow unsigned executable memory |
com.apple.security.cs.disable-library-validation | Load arbitrary plugins |
macOS Bundle Configuration
Complete macOS Configuration Example
{
"bundle": {
"icon": ["icons/icon.icns"],
"macOS": {
"minimumSystemVersion": "10.13",
"entitlements": "./Entitlements.plist",
"frameworks": [
"CoreAudio",
"./libs/libcustom.dylib",
"./frameworks/CustomFramework.framework"
],
"files": {
"embedded.provisionprofile": "./profiles/distribution.provisionprofile",
"SharedSupport/README.md": "./docs/README.md"
},
"dmg": {
"background": "./images/dmg-background.png",
"windowSize": {
"width": 660,
"height": 400
},
"appPosition": {
"x": 180,
"y": 220
},
"applicationFolderPosition": {
"x": 480,
"y": 220
}
}
}
}
}
Minimum System Version
Set the minimum supported macOS version:
{
"bundle": {
"macOS": {
"minimumSystemVersion": "12.0"
}
}
}
Default: macOS 10.13 (High Sierra)
Including Frameworks and Libraries
Bundle system frameworks or custom dylib files:
{
"bundle": {
"macOS": {
"frameworks": [
"CoreAudio",
"AVFoundation",
"./libs/libmsodbcsql.18.dylib",
"./frameworks/Sparkle.framework"
]
}
}
}
- System frameworks: Specify name only (e.g.,
"CoreAudio")
- Custom frameworks/dylibs: Provide path relative to
src-tauri
Adding Custom Files to Bundle
Include additional files in the bundle's Contents directory:
{
"bundle": {
"macOS": {
"files": {
"embedded.provisionprofile": "./profile.provisionprofile",
"SharedSupport/docs/guide.pdf": "./assets/guide.pdf",
"Resources/config.json": "./config/default.json"
}
}
}
}
Format: "destination": "source" where paths are relative to tauri.conf.json
Troubleshooting
Common Issues
DMG icons not positioned correctly on CI/CD:
- This is a known issue with headless environments
- Consider building DMGs locally or accepting default positioning
App rejected due to missing usage descriptions:
- Add all required
NS*UsageDescription keys to Info.plist
- Ensure descriptions clearly explain why access is needed
Entitlements not applied:
- Verify the entitlements file path in
tauri.conf.json
- Ensure the app is properly code-signed
Framework not found at runtime:
- Check framework path is correct relative to
src-tauri
- Verify framework is properly signed
Verification Commands
plutil -p path/to/App.app/Contents/Info.plist
codesign -d --entitlements - path/to/App.app
codesign -vvv --deep --strict path/to/App.app
find path/to/App.app -type f | head -50
Quick Reference
File Locations
| File | Location | Purpose |
|---|
Info.plist | src-tauri/Info.plist | App metadata extensions |
Entitlements.plist | src-tauri/Entitlements.plist | Capability entitlements |
DMG Background | Any path in project | DMG window background |
Localized strings | src-tauri/infoplist/<lang>.lproj/ | Localized Info.plist values |
Build Output Locations
src-tauri/target/release/bundle/
macos/
<ProductName>.app # Application bundle
dmg/
<ProductName>_<version>_<arch>.dmg # DMG installer