macOS Deployment
Publishing
Publish your XPF application for macOS from the command line:
dotnet publish -r osx-arm64 -c Release --self-contained
For Intel Macs:
dotnet publish -r osx-x64 -c Release --self-contained
Always publish from the command line. Visual Studio publishing can produce incomplete output that is missing native libraries.
App bundle structure
macOS applications must be packaged as .app bundles for distribution. An .app bundle is a directory with the following structure:
MyApp.app/
Contents/
Info.plist
MacOS/
MyApp (executable or launch script)
Resources/
MyApp.icns (application icon)
Info.plist
Create an Info.plist with your application metadata:
<?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>CFBundleName</key>
<string>MyApp</string>
<key>CFBundleDisplayName</key>
<string>My Application</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.myapp</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleExecutable</key>
<string>MyApp</string>
<key>CFBundleIconFile</key>
<string>MyApp.icns</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
Project settings
The following .csproj settings are important for macOS deployment:
<PropertyGroup>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>osx-arm64</RuntimeIdentifier>
</PropertyGroup>
Do not set IncludeNativeLibrariesForSelfExtract to true. This is incompatible with macOS and will cause your application to fail at runtime with "Failed to create CoreCLR".
Code signing
All macOS applications must be code signed for distribution. When signing XPF applications:
- Sign individual files, not the bundle as a whole. Do not use the
--deepflag withcodesign, as it may miss files or apply incorrect entitlements. - Sign all
.dylibfiles and the main executable before signing the.appbundle.
# Sign individual binaries first
find MyApp.app -name "*.dylib" -exec codesign --force --sign "Developer ID Application: Your Name" {} \;
codesign --force --sign "Developer ID Application: Your Name" MyApp.app/Contents/MacOS/MyApp
# Then sign the bundle
codesign --force --sign "Developer ID Application: Your Name" MyApp.app
Notarization
For distribution outside the Mac App Store, Apple requires applications to be notarized. Use notarytool:
# Create a ZIP for notarization
ditto -c -k --keepParent MyApp.app MyApp.zip
# Submit for notarization
xcrun notarytool submit MyApp.zip --apple-id "you@example.com" \
--team-id "YOUR_TEAM_ID" --password "app-specific-password" --wait
# Staple the notarization ticket
xcrun stapler staple MyApp.app
DMG creation
To distribute as a .dmg disk image:
hdiutil create -volname "MyApp" -srcfolder MyApp.app -ov MyApp.dmg
Parcel (Preview)
The Avalonia Parcel tool can automate the entire macOS packaging workflow, including .app bundle creation, code signing, notarization, and .dmg generation for XPF applications. Contact the Avalonia team for access to the preview.
Dock visibility
To control whether your application appears in the macOS Dock, see macOS: Dock Visibility.
Application name
To set the name shown in the macOS menu bar (instead of "Avalonia Application"), see macOS: Application Name.
ReadyToRun
Enable ReadyToRun for faster startup:
<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
See Performance Optimization for details.