Repository navigation
.NET 11 release notes
We're excited to announce our .NET 11 SDK release!
Note: these are the base SDKs that add support for the platforms in question, if you are looking for .NET MAUI (which is built on top of our SDKs), go here instead: https://docs.microsoft.com/en-us/dotnet/maui/.
Getting Started | What's New | Known Issues | Feedback | FAQ
This release consists of the following versions:
- iOS: 27.2.11039
- tvOS: 27.2.11039
- macOS: 27.2.11039
- Mac Catalyst: 27.2.11039
This release requires Xcode 27.2 or later, which requires macOS Tahoe 26.6 or later.
Apps can target these minimum OS versions:
- iOS: 15.0
- macOS: 14.0
- tvOS: 15.0
- Mac Catalyst: 17.0
Note: while we support macOS 14, we're only testing on OS versions that Apple supports. At the time of this writing this means we're only testing on macOS 15+.
The first step is to install .NET 11.0.100.
Then install the workload corresponding with the desired platform:
$ dotnet workload install ios # other workloads: macos, tvos, and maccatalystCreate new app from a template with:
$ dotnet new ios # 'dotnet new list --tag Mobile' will show all available templatesFinally build and run the new app in the simulator
$ dotnet runThis release contains SDKs for the following four platforms: iOS, tvOS, Mac Catalyst and macOS, and has support and bindings for the OS versions that were shipped with Xcode 27.2:
- iOS 27.2
- macOS 27.2
- tvOS 27.2
- Mac Catalyst 27.2
iOS, tvOS and Mac Catalyst apps now use CoreCLR, joining macOS, which has used CoreCLR since .NET 6. NativeAOT remains a separate, opt-in deployment option.
CoreCLR uses ReadyToRun (R2R) compilation and its interpreter instead of Mono AOT and the Mono interpreter. Release builds compile the app ahead of time with R2R. Debug builds run your code in the interpreter, which supports debugging and makes builds faster. The interpreter is also available for Release builds, for code that couldn't be ahead of time compiled.
References:
- https://github.com/dotnet/macios/pull/25050
- https://github.com/dotnet/macios/pull/24437
- https://github.com/dotnet/docs/issues/56478
The SDK now processes assemblies separately from the trimmer. When nothing needs trimming, it skips the trimmer (ILLink) completely.
Trimmed CoreCLR apps and NativeAOT apps use a new trimmable-static registrar, which lets the trimmer remove unused Objective-C type information. Untrimmed simulator builds use the partial-static registrar to build faster.
Device builds are still trimmed by default, even in Debug. You can speed up incremental Debug builds for devices by turning off trimming and using the partial-static registrar:
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TrimMode>copy</TrimMode>
<Registrar>partial-static</Registrar>
</PropertyGroup>The tradeoff is that Debug and Release builds will differ more, because Release builds are trimmed by default. Bugs caused by code that isn't trimmer-safe might only show up in Release builds.
Note
For technical reasons setting PublishTrimmed=false isn't allowed, but setting TrimMode=copy will disable trimming for all assemblies, and have the same effect.
References:
- https://github.com/dotnet/macios/pull/25909
- https://github.com/dotnet/macios/pull/26346
- https://github.com/dotnet/macios/pull/26409
- https://github.com/dotnet/macios/pull/26556
- https://github.com/dotnet/macios/pull/26610
- https://github.com/dotnet/macios/pull/26613
You can now pick a device with dotnet run --device or the Device MSBuild property. For example, to run on a physical iPhone:
dotnet run -f net11.0-ios -r ios-arm64 --device "My iPhone"The new DeployToDevice target deploys an already-built iOS or tvOS app without rebuilding it, including when using dotnet run --no-build.
Additional improvements:
-
dotnet run --environment NAME=VALUEpasses environment variables to the app. - Set
WaitForExitto wait for the app to exit, andStandardOutputPathorStandardErrorPathto write app output to a file. This works on all four platforms. - When you pick a simulator interactively, running simulators are listed first. Error messages are also clearer when a simulator runtime is missing.
References:
- https://github.com/dotnet/macios/blob/main/docs/building-apps/build-properties.md#device
- https://github.com/dotnet/macios/pull/25977
- https://github.com/dotnet/macios/pull/24824
- https://github.com/dotnet/macios/pull/25715
- https://github.com/dotnet/macios/pull/25772
- https://github.com/dotnet/macios/pull/25483
dotnet watch now supports Hot Reload on macOS, Mac Catalyst, and iOS/tvOS simulators and physical devices. Physical devices can connect over USB or Wi-Fi.
The SDK checks that your build settings work with Hot Reload. On macOS and Mac Catalyst, dotnet watch starts a new copy of the app, waits for it to exit, and prints its output to the terminal.
References:
- https://github.com/dotnet/macios/pull/24922
- https://github.com/dotnet/macios/pull/25738
- https://github.com/dotnet/macios/pull/26070
New MSTest-based templates run tests inside an Apple app, with the appropriate UIKit or AppKit run loop:
dotnet new iostestdotnet new tvostestdotnet new maccatalysttestdotnet new macostest
Run the tests with dotnet test.
References:
The new AppManifestEntry item can add, override or remove top-level Info.plist entries from the project file. These entries are applied after the main manifest, partial manifests and generated values:
<ItemGroup>
<AppManifestEntry Include="NSCameraUsageDescription" Type="String" Value="Take photos." />
<AppManifestEntry Include="UIFileSharingEnabled" Type="Boolean" Value="true" />
<AppManifestEntry Include="ObsoleteKey" Type="Remove" />
</ItemGroup>You can now optimize PNG images, property lists, and localization files on all four platforms. PNG and property-list optimization is on by default for Release builds on iOS, tvOS, and Mac Catalyst. Resources in referenced libraries use the app's optimization settings.
References:
Mac Catalyst projects can now embed a network app extension.
Reference: https://github.com/dotnet/macios/pull/25940
Set EnableCrashReport=true to have CoreCLR write a JSON crash report when the app crashes. By default, reports are saved in a folder inside the app's caches directory.
Generated .dSYM bundles are now copied to the publish directory by default; set CopyDSYMToPublishDirectory=false to turn this off. Debug symbols from XCFrameworks are copied next to the app's symbols so they are included when archiving, and NativeAOT builds on macOS and Mac Catalyst now generate .dSYM bundles by default.
References:
- https://github.com/dotnet/macios/pull/26134
- https://github.com/dotnet/macios/pull/26041
- https://github.com/dotnet/macios/pull/25979
- https://github.com/dotnet/macios/pull/26197
.NET 11 iOS, tvOS and Mac Catalyst apps use CoreCLR. Setting UseMonoRuntime=true produces a build error; remove the setting when upgrading. Apps that require Mono must remain on .NET 10. macOS continues to use CoreCLR.
RuntimeInformation.FrameworkDescription now returns .NET instead of Mono, and native runtime libraries, symbols, and stack frames use CoreCLR names. Update any tools that look for Mono names. In app code, check whether a feature is supported instead of checking which runtime is running.
Reference: https://github.com/dotnet/docs/issues/56476
Remove Mono-specific settings from .NET 11 projects, or condition them so they apply only when targeting .NET 10:
-
RunAotCompilation=trueandAotAssemblies=trueproduce build errors with CoreCLR. -
UseInterpreter,MtouchInterpreter,EnableSGenConc,MtouchEnableSGenConc,MtouchUseLlvm,MtouchFloat32andMonoUseCompressedInterfaceBitmapno longer configure the CoreCLR runtime; the SDK warns about unsupported settings. -
AotCompileMaxDegreeOfParallelismno longer controls compilation of CoreCLR apps.
Mono AOT and LLVM options do not configure R2R. Use the workload's R2R defaults rather than translating Mono compiler settings one-to-one. In particular, selecting individual assemblies with MtouchInterpreter no longer applies.
Mono environment variables such as MONO_LOG_*, MONO_GC_*, MONO_INTERPRETER_OPTIONS, MONO_DEBUG, MONO_PATH and MONO_SDB_ENV_OPTIONS no longer configure the runtime. Use documented CoreCLR configuration where an equivalent exists; changing the prefix to DOTNET_ or COMPlus_ is not sufficient.
References:
- https://github.com/dotnet/macios/pull/26042
- https://github.com/dotnet/docs/issues/56477
- https://github.com/dotnet/docs/issues/56478
- https://github.com/dotnet/docs/issues/56479
Native code can no longer link to libmonosgen-2.0 and call the Mono mono_* embedding APIs. CoreCLR on these platforms has no direct replacement for this API surface.
Normal P/Invoke, LibraryImport and Objective-C interop are unaffected. For custom native-to-managed callbacks, use supported interop mechanisms such as [UnmanagedCallersOnly] and C# function pointers.
Reference: https://github.com/dotnet/docs/issues/56482
CoreCLR does not support MarshalManagedExceptionMode=UnwindNativeCode; this produces error MX0185. Remove this setting and catch managed exceptions before they cross native code, or choose a supported exception-marshaling policy.
Similarly, MarshalObjectiveCExceptionMode=UnwindManagedCode is not supported with CoreCLR. Also note that MarshalManagedExceptionMode=Disable is equivalent to Abort on CoreCLR, rather than Mono's UnwindNativeCode behavior.
References:
- https://github.com/dotnet/docs/issues/56481
- https://github.com/dotnet/macios/blob/main/docs/building-apps/build-properties.md#marshalmanagedexceptionmode
- https://github.com/dotnet/macios/blob/main/docs/building-apps/build-properties.md#marshalobjectivecexceptionmode
dotnet-trace and .nettrace files remain supported, but CoreCLR runtime events replace Mono events. Event IDs, payloads, ordering and stack information may differ even for providers with the same name. The Mono-only Microsoft-DotNETRuntimeMonoProfiler provider is no longer available.
Crash log text and runtime module names also change. CoreCLR still writes the crashing thread's managed stack to the Apple console/device log, and Apple's standard crash reports still work. The optional CoreCLR crash reporter writes JSON files, not binary dumps that you can open in SOS.
Update any tools that read traces or crash reports, and test custom native signal handlers with CoreCLR.
References:
Previously, setting PublishTrimmed=true was allowed. In .NET 11, explicitly setting PublishTrimmed to either true or false produces a build error in non-NativeAOT builds, because setting it in the project file can cause inconsistent build behavior.
Remove explicit PublishTrimmed settings from project files and shared build configuration. Use TrimMode to control trimming instead (copy, partial or full); for example:
<PropertyGroup>
<TrimMode>copy</TrimMode>
</PropertyGroup>The SDK sets PublishTrimmed automatically and skips ILLink when there is nothing to trim. NativeAOT still requires trimming, and the SDK's automatic PublishTrimmed=true setting for PublishAot=true is allowed.
References:
- https://github.com/dotnet/macios/pull/24335
- https://github.com/dotnet/macios/pull/25909
- https://github.com/dotnet/runtime/issues/108269
Compared with the initial .NET 10 release, the minimum supported deployment targets are:
| Platform | .NET 10 | .NET 11 |
|---|---|---|
| iOS | 12.2 | 15.0 |
| tvOS | 12.2 | 15.0 |
| macOS | 12.0 | 14.0 |
| Mac Catalyst | 15.0 | 17.0 |
Update SupportedOSPlatformVersion if the project targets an older version.
References:
- https://github.com/dotnet/macios/blob/dotnet-10.0.1xx-xcode26.0-11017/Make.config
- https://github.com/dotnet/macios/blob/dotnet-11.0.1xx-rc2-12212/Make.config
If SupportedOSPlatformVersion is 27.0 or later, macOS and Mac Catalyst Release builds now build only for the current Mac's architecture instead of creating an x64/arm64 universal app.
Apps targeting older OS versions still build universal binaries by default. You can still set RuntimeIdentifier or RuntimeIdentifiers to build for a specific architecture or create a universal app.
Reference: https://github.com/dotnet/macios/pull/26636
iOS and Mac Catalyst apps built with Xcode 27 must adopt the scene-based lifecycle. Apps that still use only the legacy app-delegate lifecycle can crash at launch on iOS 27.
Add the appropriate scene delegate and UIApplicationSceneManifest configuration, following Apple's migration guidance. This is an Apple requirement, not a CoreCLR requirement, and also affects .NET 10 apps built with Xcode 27.
Reference: https://github.com/dotnet/macios/issues/26837
The MD_APPLE_SDK_ROOT environment variable and the AppleSdkRoot setting in ~/Library/Preferences/maui/Settings.plist or ~/Library/Preferences/Xamarin/Settings.plist are no longer used to select Xcode in .NET 11.
Use the XcodeLocation MSBuild property/environment variable, DEVELOPER_DIR, or the system selection configured with xcode-select instead.
Reference: https://github.com/dotnet/macios/pull/24021
Setting NoBindingEmbedding=false produces a deprecation warning. Remove the setting (or keep the default, true) so native libraries are placed in a .resources folder next to the binding assembly instead of inside the assembly. Embedding is not supported for XCFrameworks, and NoBindingEmbedding=false will become a build error in .NET 12.
Reference: https://github.com/dotnet/macios/pull/25962
See Known issues
File issues here: https://github.com/dotnet/macios/issues/.