Cross-platform desktop development for macOS and Windows -- platform abstractions, UI convention differences, and multi-platform CI/CD. Activate on: cross-platform app, macOS and Windows, platform differences, DMG installer, MSI installer, NSIS installer, Cmd vs Ctrl, platform abstractions, menu bar differences, native conventions. NOT for: mobile apps, web-only apps, Tauri-specific internals (use rust-tauri-development).
Instrucciones de origen · Vista previa de solo lectura
license
Apache-2.0
name
cross-platform-desktop
description
Cross-platform desktop development for macOS and Windows -- platform abstractions, UI convention differences, and multi-platform CI/CD. Activate on: cross-platform app, macOS and Windows, platform differences, DMG installer, MSI installer, NSIS installer, Cmd vs Ctrl, platform abstractions, menu bar differences, native conventions. NOT for: mobile apps, web-only apps, Tauri-specific internals (use rust-tauri-development).
{"category":"Desktop & Native","tags":["cross-platform","desktop","macos","windows","native","platform-abstraction"],"pairs-with":[{"skill":"rust-tauri-development","reason":"Tauri is the primary cross-platform desktop framework"},{"skill":"rust-app-distribution","reason":"Platform-specific signing, packaging, and distribution"},{"skill":"github-actions-pipeline-builder","reason":"CI/CD matrix builds for multiple platforms"}]}
Build desktop applications that ship on macOS AND Windows. This skill covers the platform differences that break your app, the abstraction strategies that save your sanity, and the CI/CD discipline that catches problems before users do.
When to Use / Do NOT Use For
Use for: Desktop apps targeting macOS + Windows, framework evaluation (Tauri vs Electron vs Flutter), platform-convention-aware UI design, multi-platform CI/CD, debugging cross-platform rendering/behavior.
Do NOT use for: Web-only apps | Mobile apps | Single-platform native (SwiftUI/WinUI) | Linux-only desktop
Framework Decision Matrix (2025-2026)
Factor
Tauri v2
Electron
Flutter Desktop
Bundle size
2-10 MB
80-150 MB
15-30 MB
Idle memory
30-40 MB
150-300 MB
60-100 MB
Rendering
Native webview (varies per OS)
Bundled Chromium (identical)
Skia engine (identical)
Backend
Rust
Node.js
Dart
Plugin ecosystem
Growing (50+ official)
Mature (thousands)
Moderate
Security model
Deny-by-default
Open by default
Sandboxed
Cross-platform rendering
WebKit (macOS) vs Chromium (Windows)
Chromium everywhere
Skia everywhere
Best for
Performance, security, small bundle
Web teams, pixel-perfect parity
Custom UI, animation
Choose Tauri when performance and security matter and you accept rendering differences.
Choose Electron when pixel-identical rendering across platforms is non-negotiable.
Choose Flutter when you also target mobile and want one widget toolkit everywhere.
Use a matrix strategy to build on native runners for each platform. The full pipeline YAML is in rust-app-distribution -- the key pattern:
strategy:fail-fast:falsematrix:include:-platform:macos-latest# ARM Mac (M-series)target:aarch64-apple-darwin-platform:macos-13# Intel Mactarget:x86_64-apple-darwin-platform:windows-latesttarget:x86_64-pc-windows-msvcruns-on:${{matrix.platform}}
macOS universal binary (ARM + Intel in one): use target universal-apple-darwin with rustup target add aarch64-apple-darwin x86_64-apple-darwin.
/* Tauri injects data-platform attribute (configure in setup) */[data-platform="macos"].titlebar {
padding-left: 80px; /* Space for traffic lights */
}
[data-platform="windows"].titlebar {
padding-right: 140px; /* Space for min/max/close */
}
Testing Across Platforms
Local Development
Primary dev machine: Build and test natively
Secondary platform: VM (Parallels/VMware for Windows on Mac, or vice versa), or dedicated hardware
Quick check: CI runners catch build failures even without local testing
Automated Testing in CI
# Run tests on both platforms in CItest:strategy:matrix:os: [macos-latest, windows-latest]
runs-on:${{matrix.os}}steps:-uses:actions/checkout@v4-run:cargotest--manifest-pathsrc-tauri/Cargo.toml-run:npmci&&npmtest
Screenshot Comparison
Use headless browser testing (Playwright) in CI to screenshot the app on each platform and diff the results. Catches rendering regressions across WebKit/WebView2.
Anti-Patterns
1. Hardcoded Paths
Symptom:fs.readFile("/Users/...") or fs.readFile("C:\\Users\\...")Fix: Use dirs crate (Rust) or @tauri-apps/api/path (JS). Never assume separators.
2. Testing on One Platform Only
Symptom: "Works on my Mac" ships broken on Windows.
Fix: CI matrix builds on both platforms. Period.
3. Ignoring Close-vs-Quit Semantics
Symptom: macOS users expect app to stay running when closing window. Windows users expect it to quit.
Fix: Follow each platform's convention explicitly.
4. Platform-Specific Fonts Without Fallbacks
Symptom: "SF Pro" renders as Times New Roman on Windows.
Fix: Full font stack: -apple-system, "Segoe UI", Roboto, sans-serif.
5. Pixel-Based Layouts That Break at Fractional Scaling
Symptom: UI looks fine on macOS Retina, misaligned at 125%/150% on Windows.
Fix: Use logical CSS units, SVG icons, test at multiple DPI settings.
6. Assuming WebKit Behavior on Windows
Symptom: CSS or JS works on macOS (WebKit) but breaks on Windows (Chromium).
Fix: Test both. Use feature detection. Check compat tables.
7. One Giant Installer for All Platforms
Symptom: Trying to create a universal artifact.
Fix: Each platform gets its own format: DMG (macOS), NSIS/MSI (Windows).
8. Not Handling Windows Long Path Limits
Symptom: File operations fail on deeply nested directories.
Fix: Check path length, or use \\?\ extended-length prefix on Windows.
Quality Checklist
[ ] App builds and runs on both macOS and Windows
[ ] CI/CD matrix builds both platforms on every push
[ ] Keyboard shortcuts use Cmd on macOS, Ctrl on Windows
[ ] Shortcut hints in UI reflect current platform dynamically
[ ] Close button follows platform convention (hide on macOS, quit on Windows)
[ ] Menu bar is global on macOS, in-window on Windows
[ ] System tray works on both platforms
[ ] File paths resolved via platform APIs (never hardcoded)
[ ] Font stack includes fallbacks for both platforms
[ ] Dark mode detected and applied on both platforms
[ ] Tested at 1x, 1.25x, 1.5x, and 2x display scaling
[ ] Installers generated: DMG for macOS, NSIS or MSI for Windows
[ ] Code signing configured for both platforms (see rust-app-distribution)
[ ] No platform-specific CSS without feature detection
[ ] Window state (size, position) persisted correctly per platform