All tests run on an 8-year-old MacBook Air (Intel). Ships as universal binary.
A universal binary runs natively on both Intel Macs and Apple Silicon. Not via Rosetta — actually natively, with the CPU running its own instruction set.
With Tauri and Rust, building one is surprisingly straightforward.
Add both targets
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
That's the Intel target and the Apple Silicon target respectively.
Build both and combine
# Build for Intel
cargo build --release --target x86_64-apple-darwin
# Build for Apple Silicon
cargo build --release --target aarch64-apple-darwin
# Combine into a universal binary
lipo -create \
target/x86_64-apple-darwin/release/myapp \
target/aarch64-apple-darwin/release/myapp \
-output target/universal/myapp
lipo is Apple's tool for combining architecture slices into a single binary. It ships with Xcode Command Line Tools.
Tauri's built-in support
Tauri v2 handles this for you:
cargo tauri build --target universal-apple-darwin
One command. Tauri builds both architectures, runs lipo, packages the DMG. Done.
The sidecar problem
If your app bundles sidecar binaries (Swift CLIs, ADB, ffmpeg, etc.), each one also needs to be a universal binary.
For binaries you compile yourself:
# Build Swift CLI for both architectures
swiftc -target x86_64-apple-macosx10.15 MyUtil.swift -o MyUtil-x86
swiftc -target arm64-apple-macosx11.0 MyUtil.swift -o MyUtil-arm64
lipo -create MyUtil-x86 MyUtil-arm64 -output MyUtil
For third-party binaries (like ADB): check if the vendor provides a universal binary. If not, you'll need to bundle both and select the right one at runtime based on std::env::consts::ARCH.
Verifying the output
file target/universal/myapp
# myapp: Mach-O universal binary with 2 architectures:
# [x86_64:Mach-O 64-bit executable x86_64]
# [arm64:Mach-O 64-bit executable arm64]
lipo -info target/universal/myapp
# Architectures in the fat file: x86_64 arm64
If you see both architectures, you're done.
Binary size
Universal binaries are roughly 2x the size of a single-architecture binary. For a typical Tauri app this means going from ~5MB to ~10MB. Acceptable for a DMG download.
Hiyoko PDF Vault → https://hiyokoko.gumroad.com/l/HiyokoPDFVault
X → @hiyoyok
Top comments (0)