Dioxus CLI provides comprehensive bundling capabilities to package your application for production across all supported platforms - web, desktop, and mobile.
Build vs Bundle
Understand the difference between these commands:
dx build - Compiles your application and assets into an executable/WASM:
Produces runnable binaries
Optimizes for target platform
Processes assets and static files
Output: executable + assets in out_dir
dx bundle - Packages the built application into distributable formats:
Creates installers, app bundles, packages
Platform-specific formats (DMG, MSI, AppImage, etc.)
Includes dependencies and resources
Output: ready-to-distribute packages
# Build for production
dx build --release --platform desktop
# Then bundle into installer
dx bundle --release --platform desktop --package-types dmg
Production Builds
Web (WASM)
Build an optimized web application:
dx build --platform web --release
Output structure:
dist/
├── index.html # Entry point
├── assets/
│ ├── dioxus/
│ │ ├── my-app.js # JS bindings
│ │ └── my-app.wasm # Optimized WASM
│ ├── tailwind.css # Processed styles
│ └── [hashed-assets] # Static assets with cache-busting hashes
└── [public files] # Copied from public_dir
Optimizations Applied:
WASM Optimization via wasm-opt:
Dead code elimination
Function inlining
Size reduction (typically 30-50%)
Asset Processing :
Hash-based filenames for cache busting
Tailwind CSS purging (unused styles removed)
Image optimization (via manganis)
Optional Pre-Compression :
[ web ]
pre_compress = true
Generates .gz and .br files for faster loading.
WASM Optimization Levels
Configure in Dioxus.toml:
[ web . wasm_opt ]
# "z" (default) - Aggressive size optimization
# "s" - Size optimization
# "0" - No optimization (fastest builds)
# "1-4" - Speed optimization levels
level = "z"
# Keep function names for better error messages
keep_names = false
# Keep full debug symbols (large file size)
debug = false
Performance Comparison:
Level Build Time WASM Size Runtime Speed zSlow Smallest Good sMedium Small Good 0Fast Large Good 4Slowest Largest Fastest
Desktop Applications
Build native desktop apps:
# macOS
dx build --platform desktop --release --target aarch64-apple-darwin
# Windows
dx build --platform desktop --release --target x86_64-pc-windows-msvc
# Linux
dx build --platform desktop --release --target x86_64-unknown-linux-gnu
Output:
Standalone executable
Bundled webview (Wry/Tao)
Assets embedded or copied alongside
Mobile Applications
iOS:
dx build --platform ios --release
Output: Xcode project + compiled library
Android:
dx build --platform android --release
Output: APK or AAB (depending on Gradle configuration)
macOS Bundles
Create macOS app bundles and installers:
# App bundle (.app)
dx bundle --platform macos --package-types app
# Disk image (.dmg)
dx bundle --platform macos --package-types dmg
Configuration:
[ bundle ]
identifier = "com.mycompany.myapp"
icon = [ "assets/icon.icns" ]
[ macos ]
identifier = "com.mycompany.myapp.macos"
info_plist = "macos/Info.plist"
entitlements = "macos/entitlements.plist"
Entitlements (macos/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 />
</ dict >
</ plist >
macOS bundles require code signing for distribution. Use Xcode or codesign tool.
Windows Installers
# MSI installer
dx bundle --platform windows --package-types msi
# NSIS installer (.exe)
dx bundle --platform windows --package-types nsis
Configuration:
[ bundle ]
identifier = "com.mycompany.myapp"
icon = [ "assets/icon.ico" ]
publisher = "My Company"
[ windows ]
identifier = "com.mycompany.myapp.windows"
Linux Packages
# Debian package
dx bundle --platform linux --package-types deb
# RPM package
dx bundle --platform linux --package-types rpm
# AppImage (portable)
dx bundle --platform linux --package-types appimage
Configuration:
[ bundle ]
identifier = "com.mycompany.myapp"
icon = [ "assets/icon.png" ]
category = "Utility"
[ linux ]
identifier = "com.mycompany.myapp.linux"
Categories (Linux desktop files):
AudioVideo, Audio, Video
Development, Education, Game
Graphics, Network, Office
Science, Settings, System
Utility
iOS Bundles
dx bundle --platform ios --package-types ios-bundle
Output: .app bundle in dist/
Configuration:
[ ios ]
identifier = "com.mycompany.myapp.ios"
deployment_target = "14.0"
info_plist = "ios/Info.plist"
entitlements = "ios/entitlements.plist"
iOS bundles are not automatically codesigned . You must sign them before installing on devices or submitting to the App Store.
Code Signing:
# Sign the bundle
codesign --force --sign "Apple Development: Your Name" \
--entitlements ios/entitlements.plist \
dist/MyApp.app
# Verify signature
codesign --verify --verbose dist/MyApp.app
Android Packages
# APK (for testing/sideloading)
dx bundle --platform android
# AAB (for Play Store)
dx bundle --platform android --package-types aab
Configuration:
[ android ]
identifier = "com.mycompany.myapp"
min_sdk_version = 24
manifest = "android/AndroidManifest.xml"
Signing (required for release):
Create keystore:
keytool -genkey -v -keystore release.keystore \
-alias myapp -keyalg RSA -keysize 2048 -validity 10000
Sign APK:
jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA256 \
-keystore release.keystore dist/app-release.apk myapp
Asset Optimization
Automatic Asset Processing
The CLI automatically processes assets referenced via asset!():
use manganis :: asset;
const LOGO : Asset = asset! ( "./assets/logo.png" );
const STYLESHEET : Asset = asset! ( "./assets/main.css" );
Processing:
Hash calculation for cache busting
Image optimization (PNG, JPEG, WebP)
CSS minification
Path rewriting for deployment
Tailwind CSS Integration
The CLI automatically detects and processes Tailwind:
Detected by:
tailwind.config.js / tailwind.config.ts → Tailwind v3
tailwind.css → Tailwind v4
Auto-installed on first build (no manual setup required).
Build process:
Scans source files for classes
Generates minimal CSS (unused classes removed)
Minifies for production
Custom Configuration:
[ application ]
tailwind_input = "styles/input.css"
tailwind_output = "assets/styles.css"
Public Directory
Static files copied verbatim:
[ application ]
public_dir = "public"
public/
├── favicon.ico # Copied to dist/favicon.ico
├── robots.txt
└── images/
└── banner.jpg
These files are not processed or optimized - use for:
Pre-optimized images
Third-party libraries
SEO files (robots.txt, sitemap.xml)
Fullstack Applications
Client + Server Builds
Build both client and server in one command:
dx build --fullstack --release
Output:
dist/
├── public/ # Client assets (WASM, JS, HTML)
│ ├── index.html
│ └── assets/
└── server # Server executable
Static Site Generation (SSG)
Pre-render routes at build time:
dx build --fullstack --ssg --release
The server builds, runs, and generates static HTML for all routes returned by /static_routes endpoint.
Benefits:
Instant page loads (no server roundtrip)
Better SEO (crawlers see full HTML)
Reduced server load
Configuration:
#[component]
fn App () -> Element {
rsx! {
Router :: < Route > {}
}
}
// Define which routes to pre-render
#[server]
async fn static_routes () -> Vec < String > {
vec! [
"/" . to_string (),
"/about" . to_string (),
"/blog/post-1" . to_string (),
]
}
Optimization Strategies
Build Size Optimization
1. Enable LTO (Link-Time Optimization):
# Cargo.toml
[ profile . release ]
lto = true
codegen-units = 1
opt-level = "z" # Optimize for size
strip = true # Remove symbols
2. WASM Optimization:
# Dioxus.toml
[ web . wasm_opt ]
level = "z"
memory_packing = true
3. Remove Unused Dependencies:
cargo tree --duplicates
cargo bloat --release --crates
4. Feature Flags:
Disable unused features:
[ dependencies ]
dioxus = { version = "0.7" , default-features = false , features = [ "web" ] }
1. Code Splitting (for web):
Lazy load components:
use dioxus :: prelude ::* ;
#[component]
fn App () -> Element {
rsx! {
Suspense {
fallback : | _ | rsx! { "Loading..." },
LazyComponent {}
}
}
}
#[component]
fn LazyComponent () -> Element {
// Heavy component loaded on demand
rsx! { /* ... */ }
}
2. Asset Optimization:
Use WebP for images
Compress images before bundling
Use SVG for icons
Minimize CSS/JS
3. Pre-compression:
[ web ]
pre_compress = true
Generates .gz and .br files - configure your server to serve them.
Deployment
Web Deployment
Static Hosting (GitHub Pages, Netlify, Vercel):
dx build --platform web --release
# Upload dist/ directory
With Base Path (for GitHub Pages subdirectory):
[ web . app ]
base_path = "/my-repo"
Server Configuration (nginx example):
server {
root /var/www/myapp/dist;
# Serve pre-compressed files
gzip_static on ;
brotli_static on ;
# Cache assets with hashes
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable" ;
}
# SPA fallback
location / {
try_files $ uri $ uri / /index.html;
}
}
Desktop Deployment
macOS:
Build and bundle: dx bundle --platform macos --package-types dmg
Code sign the .app bundle
Notarize with Apple (for Gatekeeper)
Distribute the .dmg
Windows:
Build and bundle: dx bundle --platform windows --package-types msi
Sign the installer (optional but recommended)
Distribute the .msi
Linux:
Build for multiple formats: dx bundle --platform linux --package-types deb,appimage
Distribute packages via package managers or direct download
Mobile Deployment
iOS (App Store):
Build: dx bundle --platform ios
Open in Xcode
Configure signing & provisioning
Archive and upload to App Store Connect
Android (Play Store):
Build AAB: dx bundle --platform android --package-types aab
Sign with release keystore
Upload to Google Play Console
CI/CD Integration
GitHub Actions Example
name : Build and Deploy
on :
push :
branches : [ main ]
jobs :
build :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : Install Rust
uses : actions-rs/toolchain@v1
with :
toolchain : stable
target : wasm32-unknown-unknown
- name : Install Dioxus CLI
run : cargo install dioxus-cli
- name : Build
run : dx build --platform web --release
- name : Deploy to GitHub Pages
uses : peaceiris/actions-gh-pages@v3
with :
github_token : ${{ secrets.GITHUB_TOKEN }}
publish_dir : ./dist
strategy :
matrix :
include :
- os : ubuntu-latest
platform : linux
package : deb
- os : macos-latest
platform : macos
package : dmg
- os : windows-latest
platform : windows
package : msi
steps :
- name : Build
run : dx bundle --platform ${{ matrix.platform }} --package-types ${{ matrix.package }} --release
- name : Upload Artifacts
uses : actions/upload-artifact@v3
with :
name : ${{ matrix.platform }}-bundle
path : dist/
Troubleshooting
Large WASM Size
Check:
Is --release enabled?
Is wasm-opt running? (check logs)
Are you using opt-level = "z" in Cargo.toml?
Remove console_error_panic_hook in production
Analyze:
wasm-opt --print-function-sizes dist/assets/dioxus/my-app.wasm
Bundle Errors
Missing icon:
Error: Icon file not found: assets/icon.png
Ensure icon paths in Dioxus.toml are correct.
Invalid identifier:
Error: Bundle identifier must be reverse domain notation
Use format: com.company.app
Deployment Issues
404 on routes (SPA):
Configure server fallback to index.html for unknown routes.
WASM not loading:
Check MIME type: server must send application/wasm for .wasm files.
Assets not found:
Verify base_path in Dioxus.toml matches deployment path.
Next Steps
Configuration Configure bundle settings
Commands Learn about build commands