Migrating to Uno Platform 7.0 — Skia-only rendering
Uno Platform 7.0 removes the native UI rendering backends (native Android Views, native iOS/tvOS/macCatalyst UIKit, and the native WebAssembly DOM renderer) and makes Skia the single, implicit rendering engine on every target.
Skia already runs on every platform — desktop (Win32, WPF, X11, GTK, macOS, FrameBuffer),
Skia-on-Android, Skia-on-iOS, and Skia-on-WebAssembly. In 7.0 it becomes the only UI
rendering path: a UIElement is a plain managed object backed by a Composition.Visual
on all platforms, drawn into a single Skia surface.
This does not drop platform support: Android, iOS, macOS, Windows, Linux, and WebAssembly all remain supported — they now all render with Skia.
Important
This is a hard removal in a single major version — there is no [Obsolete] interim.
Plan to recompile every Uno library against 7.0 and update your application heads.
Who is affected
- Apps that opted out of the Skia renderer on mobile by omitting
<UnoFeatures>skiarenderer</UnoFeatures>and relying on native rendering. - Apps that used the native WebAssembly DOM renderer (
Uno.WinUI.WebAssembly). - Code that referenced native rendering types, native element hosting, or native-only
FeatureConfigurationflags (see below).
Apps already running on Skia on every target need only recompile against 7.0 and remove native bootstrap/heads.
What changed
Rendering is Skia everywhere
The NativeRenderer Uno Feature and the renderer-selection logic are gone — Skia is
always used. skiarenderer is now implicit and mandatory for
android/ios/tvos/maccatalyst; it is kept as a no-op for back-compat, so you can
leave <UnoFeatures>skiarenderer</UnoFeatures> in place or remove it — either way Skia
renders.
WebAssembly renders to a canvas through Skia; there is no per-element DOM tree, no
Uno.UI.css styling layer, and no WindowManager.ts.
If your project was created before Uno Platform 6.0 and still selects a renderer, follow the Uno 6.0 migration guide first to move to the Uno.SDK single-project model.
Packages
| Removed / changed | Migration |
|---|---|
Uno.WinUI.WebAssembly package removed (and the older Uno.WinUI.Runtime.WebAssembly) |
Use Uno.WinUI.Runtime.Skia.WebAssembly.Browser. The UI renders to a canvas; there is no DOM tree. With the Uno.SDK, the Skia browser head is referenced implicitly — there is nothing to add. |
Uno.WinUI.Skia.X11, Uno.WinUI.Skia.MacOS, and Uno.WinUI.Skia.Linux.FrameBuffer bootstrapper packages removed |
These were empty meta-packages that only redirected to the real head. With the Uno.SDK, remove the reference — the matching Uno.WinUI.Runtime.Skia.* head is referenced implicitly for executable heads. For a hand-rolled (non-Uno.SDK) head, replace it with the corresponding Uno.WinUI.Runtime.Skia.<variant> package. |
Uno.UI.BindingHelper.Android assembly removed |
Remove the reference; Skia-on-Android needs no Java/JNI binding. |
Uno.UniversalImageLoader no longer injected (Android) |
Skia handles image loading internally. If you initialized it manually, remove the ConfigureUniversalImageLoader(); call. |
Uno.UI.Maps AddIn removed |
The native Google Maps control has no core Skia equivalent — use a third-party/Skia map or custom rendering. |
Uno.WinUI UI assemblies for net*-android/ios/tvos/maccatalyst are now the Skia binaries |
Same TFM string, but binary-incompatible with previously native-built consumers. Recompile all libraries against 7.0 and remove native bootstrap. |
Xamarin.AndroidX.* transitive deps removed (AppCompat, RecyclerView, Activity, Browser, SwipeRefreshLayout) |
If your own code uses AndroidX, add explicit PackageReferences. |
Note
Referencing Uno.WinUI.WebAssembly (or the older Uno.WinUI.Runtime.WebAssembly)
alongside the Skia browser head raises the UNOB0017 build diagnostic. Removing the
explicit reference resolves it.
Public API removed
- Native base classes / identity:
BindableView(andBindable*widget wrappers),BindableUIView(andBindableUI*).UIElementno longer inherits a nativeView/UIView/DOM element. Remove casts toAndroid.Views.View/UIKit.UIView; useUIElement.Visual(Composition) and reach platform APIs via theUno.UI.Runtime.Skia.*hosts andUno.Foundation. - Native element hosting:
Uno.UI.NativeElementHosting.BrowserHtmlElement,Uno.UI.Runtime.WebAssembly.HtmlElementAttribute, andContentPresenterhosting of a nativeView/UIView/DOM element asContent. UseWebView2for HTML content, or redesign with Uno controls. On iOS, opt-in native embedding remains viaUIKitNativeElementHostingExtension(overlay-composited, reduced performance). - Native control / host types:
NativeListViewBase,NativePagedView,NativeScrollContentPresenter,NativeFramePresenter,NativePopup,RootViewController,Window : UIWindowidentity,NativeRenderTransformAdapter,IShadowChildrenProvider,CompositorThread,Uno.UI.Composition.ICompositionRoot. Use the WinUI control (ListView/Frame/Popup/…) — everything renders via Skia. - Composition:
Uno.CompositionConfiguration.Options.UseCompositorThread(the Android RenderNode compositor thread). Remove the flag; Skia composition needs no dedicated native render thread. - Legacy WebAssembly JavaScript interop:
Uno.Foundation.Interop.IJSObject,IJSObjectMetadata,JSObjectHandle,JSObject, andWebAssemblyRuntime.InvokeJSWithInterop(FormattableString)— the Uno-only managed-to-JavaScript object-marshalling mechanism (no WinUI counterpart). Migrate to the standard .NET WebAssembly interop, JSImport/JSExport fromSystem.Runtime.InteropServices.JavaScript— the recommended, source-generated path (thread-safe, CSP-compliant, noeval). The string-basedWebAssemblyRuntime.InvokeJS(string)is not removed, but it is a legacy eval-based API and is not recommended for new code.
FeatureConfiguration flags removed
The native-only flags below no longer exist; delete the calls — behavior is the unified Skia/WinUI behavior:
- Android:
ComboBox.AllowPopupUnderTranslucentStatusBar,FrameworkElement.AndroidUseManagedLoadedUnloaded,FrameworkElement.InvalidateNativeCacheOnRemeasure,Popup.UseNativePopup,NativeListViewBase.*,NativeFramePresenter.AndroidUnloadInactivePages,TextBox.UseLegacyInputScope,UIElement.UseLegacyClipping,UIElement.AlwaysClipNativeChildren,ScrollViewer.AndroidScrollbarFadeDelay,WebView.ForceSoftwareRendering,PointerRoutedEventArgs.AllowRelativeTimeStamp,TextBlock.IsJavaStringCachedEnabled/JavaStringCachedCapacity,AppBarButton.EnableBitmapIconTint,TimePickerFlyout.UseLegacyTimeSetting,NavigationView.EnableUno19516Workaround,AndroidSettings.IsEdgeToEdgeEnabled. - iOS:
Image.LegacyIosAlignment,FrameworkElement.IOsAllowSuperviewNeedsLayoutWhileInLayoutSubViews,CommandBar.AllowNativePresenterContent,DatePicker.UseLegacyStyle,TimePicker.UseLegacyStyle. - WebAssembly:
Interop.ForceJavascriptInterop,UIElement.AssignDOMXamlName,UIElement.AssignDOMXamlProperties,TextBlock.IsMeasureCacheEnabled,Cursors.UseHandForInteraction(the "hand" cursor for interactive controls is now never used). - Native (Android + iOS):
ListViewBase.AnimateScrollIntoView. - Native styling:
Style.UseUWPDefaultStyles,Style.ConfigureNativeFrameNavigation(). - Skia overlay:
TextBox.UseOverlayOnSkia.
WebView2.IsInspectable is also removed; it was an obsolete alias, so switch to
WebView2.EnableDevTools instead.
If a single codebase must target both pre-7.0 and 7.0, guard the calls with #if.
Behavioral changes (same API, different result)
Because rendering moves from Canvas/CALayer/CSS to Skia, expect subtle differences and
re-baseline visual tests:
- Rendering: gradients, corner radii, shadows/elevation, and anti-aliasing render via Skia — minor pixel differences are possible.
- Text: measurement, line-breaking, bidi, kerning, and
MaxLinesgo through HarfBuzz + SkiaSharp instead ofStaticLayout/UIKit text/DOM — possible layout shifts in text-dense UI. - Lists / scrolling: managed virtualization and scrolling replace
RecyclerView/UICollectionView/CSS overflow — fling curves, edge glows, and snap points may differ. - IME / keyboard: canvas-rendered text input with a platform IME bridge replaces the
native
EditText/UITextField— re-test CJK/emoji composition and selection visuals. - Pickers / command bars / Frame: Skia/WinUI-styled rather than native-styled — appearance changes on Android/iOS.
- Animation timing: Skia interpolation replaces
CABasicAnimation— standard easing matches; exotic timing may not.
Type-hierarchy changes (WinUI parity)
7.0 realigns several types to their WinUI base classes. Most code is unaffected — the change only breaks code that used the Uno-only members leaked by the wrong base.
MediaPlayerPresenternow derives directly fromFrameworkElement(matching WinUI) instead ofBorder, removing the extraBorderlevel. TheBorder-only surface it used to expose —Child,BorderBrush,BorderThickness,CornerRadius,Padding,BackgroundSizing,ChildTransitions— is gone, andis Borderis no longertruefor a presenter. The video surface is hosted internally, so playback andStretchare unchanged.MediaPlayerElementsets its ownBackground(black) on the template root, so letterbox bars stay black.ImageBrushnow derives from a realTileBrush(Brush → TileBrush → ImageBrush, matching WinUI) instead of directly fromBrush.AlignmentX,AlignmentY, andStretchbehave the same for callers but are now declared onTileBrush— code that referenced the static DPs by their declaring type (ImageBrush.StretchProperty,AlignmentXProperty,AlignmentYProperty) still resolves via inheritance, andis TileBrushis nowtruefor anImageBrush. Instance usage (imageBrush.Stretch, XAMLStretch="…") is unaffected.
Templates and project heads
New apps get Skia heads only. Existing apps should drop native *.Mobile / native
*.Wasm (DOM) heads in favor of the Skia heads (Skia.netcoremobile,
Skia.WebAssembly.Browser, and the desktop Skia head) and remove native bootstrap code.
Migration checklist
- Remove
<UnoFeatures>skiarenderer</UnoFeatures>(now implicit) — and any native-only feature switches. - Recompile every Uno-dependent library against 7.0.
- Remove references to the deleted assemblies/types and to native element hosting.
- Delete native-only
FeatureConfigurationcalls. - Replace the WASM DOM head with the Skia WebAssembly Browser head; remove any DOM/CSS
customization and
HtmlElementusage. - Remove manual
ConfigureUniversalImageLoader();(Android) and other native bootstrap. - Re-baseline visual/snapshot tests and re-test text, lists/scroll, IME, pickers, and safe-area/notch handling on devices.
See the Uno 6.0 migration guide for the full Android/iOS/WebAssembly Skia bootstrapping steps.