OpenMaui.Controls.Linux.Blazor 10.0.110.7

dotnet add package OpenMaui.Controls.Linux.Blazor --version 10.0.110.7
                    
NuGet\Install-Package OpenMaui.Controls.Linux.Blazor -Version 10.0.110.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OpenMaui.Controls.Linux.Blazor" Version="10.0.110.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OpenMaui.Controls.Linux.Blazor" Version="10.0.110.7" />
                    
Directory.Packages.props
<PackageReference Include="OpenMaui.Controls.Linux.Blazor" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OpenMaui.Controls.Linux.Blazor --version 10.0.110.7
                    
#r "nuget: OpenMaui.Controls.Linux.Blazor, 10.0.110.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OpenMaui.Controls.Linux.Blazor@10.0.110.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OpenMaui.Controls.Linux.Blazor&version=10.0.110.7
                    
Install as a Cake Addin
#tool nuget:?package=OpenMaui.Controls.Linux.Blazor&version=10.0.110.7
                    
Install as a Cake Tool

OpenMaui Linux Platform

A comprehensive Linux platform implementation for .NET MAUI using SkiaSharp rendering.

NuGet License GitHub

Developed by MarketAlly Pte Ltd Lead Architect: David H. Friedel Jr.

Overview

This project brings .NET MAUI to Linux desktops with native X11/Wayland support, hardware-accelerated Skia rendering, and full platform service integration.

Key Features

  • Full Control Library: 50+ controls including Button, Label, Entry, Shapes, CarouselView, RefreshView, SwipeView, and more
  • Native Integration: First-class X11 and native Wayland support (xdg-shell, wp_viewporter, fractional-scale-v1, zxdg_decoration_manager_v1, zwp_primary_selection_v1) — programmatically selectable or auto-detected
  • Accessibility: AT-SPI2 screen reader support and high contrast mode
  • Platform Services: Native wl_data_device_manager clipboard and drag-and-drop (no wl-clipboard subprocess required), zwp_primary_selection_v1 middle-click paste, file picker, notifications, global hotkeys, CUPS printing, system tray icons via StatusNotifierItem
  • Input Methods: IBus / XIM on X11 + native zwp_text_input_v3 on Wayland with full delete_surrounding_text round-trip for compositor-integrated IMEs (GNOME Pinyin/Hangul/Anthy, native Fcitx5)
  • High DPI: Automatic scale factor detection for GNOME, KDE, and X11; fractional scale handled via Wayland viewporter for pixel-exact rendering at non-integer scales (1.25x, 1.5x, 1.75x)
  • Theming: AppThemeBinding live propagation across the entire view tree — CollectionView items, pushed pages, Shell content, and flyout regions all flip on theme toggle
  • Window decorations: Server-side decorations (KDE/Sway) or client-side titlebar drawn in Skia with full drag/resize/close/maximize/minimize (GNOME/Mutter)
  • MediaElement: Opt-in OpenMaui.Controls.Linux.MediaElement package backs CommunityToolkit.Maui.MediaElement with GStreamer (playbin + appsink → Skia). MediaHardwareAcceleration.Prefer boosts VA-API / NVDEC / V4L2 / MediaSDK decoder ranks when those plugins are installed
  • WebView: WPE WebKit composited inside the Skia tree (no GTK widget, no reparenting) on native Wayland and X11, with context menus, clipboard, JavaScript dialogs, file chooser, permissions, web notifications, downloads, spell checking, link cursors, EvaluateJavaScriptAsync results and a backend-neutral WebKit content API; WebKitGTK remains the GTK-mode fallback. Libraries derive from the public LinuxWebViewHandler for what WebView2 and WKWebView give them elsewhere (ILinuxWebView: navigation and new-window decisions, HTTP status, response and download handling with the desktop's Save dialog, zoom, page capture and save as PDF)
  • HybridWebView: MAUI's HybridWebView on the same WebKit engines, as on iOS and Mac Catalyst: the web app served from app://0.0.0.1/ out of Resources/Raw/{HybridRoot}, MAUI's own hybridwebview.js, SendRawMessage/RawMessageReceived, InvokeJavaScriptAsync, window.HybridWebView.InvokeDotNet, and WebResourceRequested for app-origin requests
  • Blazor Hybrid: Opt-in OpenMaui.Controls.Linux.Blazor package backs BlazorWebView (Microsoft.AspNetCore.Components.WebView.Maui) on the WPE WebView
  • Maps: Opt-in OpenMaui.Controls.Linux.Maps package backs Microsoft.Maui.Controls.Maps with OpenStreetMap raster tiles in Skia — pan/zoom, pin & polyline overlays, persistent XDG tile cache. Plus a standalone SkiaMap view for code-first map UI
  • PDF: Opt-in OpenMaui.Controls.Linux.Pdf package renders PDF pages with Google's PDFium (bundled for x64 and arm64): SkiaPdfView for a scrolling, zoomable document view, PdfiumDocument for pages as bitmaps and their text, and .UseLinuxPdf() makes Syncfusion's PdfToImageConverter (and so SfPdfViewer) render
  • Syncfusion: Opt-in OpenMaui.Controls.Linux.Syncfusion package runs Syncfusion .NET MAUI controls (lists and trees, tabs, charts, inputs and drop-downs, Carousel, Rotator, SignaturePad, SfPopup): call .UseLinuxSyncfusion() instead of .ConfigureSyncfusionCore(). Bring your own Syncfusion license
  • Effects: MAUI's effects pipeline (ConfigureEffects, RoutingEffect to PlatformEffect with the Skia view as Control), with per-view routed pointer, key and bounds events on SkiaView for a platform effect to hook
  • Third-party libraries: popular MAUI libraries (CommunityToolkit.Maui, CommunityToolkit.Mvvm, LiveCharts2, ReactiveUI, Prism, SkiaSharp views) run unmodified, measured by a separate compatibility suite and published in the scorecard

Quick Start

Installation

# Install the templates
dotnet new install OpenMaui.Linux.Templates

# Create a new project (choose one):
dotnet new openmaui-linux -n MyApp           # Code-based UI
dotnet new openmaui-linux-xaml -n MyApp      # XAML-based UI (recommended)

cd MyApp
dotnet run

Manual Installation

dotnet add package OpenMaui.Controls.Linux

Optional: MediaElement (video / audio playback)

CommunityToolkit.Maui.MediaElement on Linux requires the opt-in sibling package that adds the GStreamer-backed handler:

dotnet add package CommunityToolkit.Maui.MediaElement
dotnet add package OpenMaui.Controls.Linux.MediaElement

Then in your MauiProgram.cs:

builder
    .UseMauiApp<App>()
    .UseMauiCommunityToolkitMediaElement(isAndroidForegroundServiceEnabled: false)
    .UseLinux()
    .UseLinuxMediaElement();   // Linux backend; no-op on Windows/Android/iOS/macCatalyst

System dependencies (GStreamer + plugin sets):

# Fedora
sudo dnf install gstreamer1-plugins-good gstreamer1-plugins-bad-free \
                 gstreamer1-plugins-ugly-free gstreamer1-plugin-libav gstreamer1-vaapi

# Ubuntu/Debian
sudo apt install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
                 gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-vaapi

gstreamer1-vaapi enables hardware-accelerated decode on Intel/AMD GPUs; substitute the nvdec plugin for NVIDIA. Software decode works without either.

To explicitly bias playbin toward the hardware decoders when they are installed:

using Microsoft.Maui.Platform.Linux.MediaElement.Services;

builder.UseLinuxMediaElement(MediaHardwareAcceleration.Prefer);

Auto keeps the default behavior, Prefer bumps HW decoder factory ranks above SW, and Disable demotes them.

Optional: Syncfusion controls

Linux apps build plain net10.0 and so get Syncfusion's platform-neutral assemblies, which have no native drawing or touch. The opt-in bridge package supplies them on OpenMaui's renderer:

dotnet add package OpenMaui.Controls.Linux.Syncfusion

Then call UseLinuxSyncfusion() in place of ConfigureSyncfusionCore() (on the other platforms it calls ConfigureSyncfusionCore() for you):

builder
    .UseMauiApp<App>()
    .UseLinux()
    .UseLinuxSyncfusion();

SfView-based controls (ListView, TreeView, TabView, Charts, the inputs and the rest) lay out, draw their text and graphics, and receive touch, tap, double-tap, right-tap, long-press, drag, wheel, ctrl+wheel pinch and keyboard input. SfCarousel, SfRotator, SfSignaturePad, SfInteractiveScrollView, SfDataGrid's scroller and SfImageEditor's image view get their native views from the package; SfComboBox and SfAutocomplete drop-downs and SfPopup (and the controls that open one) show as overlays. SfDataGrid, SfScheduler and SfPullToRefresh take the mouse and keyboard as on Windows (column and row resizing and dragging, right-click and context menus, appointment drag and resize, pull with a mouse drag), and SfImageEditor edits, saves and exports images. Not covered yet: SfScheduler's desktop horizontal resource view. The package does not include Syncfusion's assemblies; you need your own Syncfusion license.

Optional: PDF (PDFium)

Showing PDFs on Linux uses the opt-in sibling package, which bundles Google's PDFium (Apache-2.0) for linux-x64 and linux-arm64, so the host needs nothing installed:

dotnet add package OpenMaui.Controls.Linux.Pdf
builder
    .UseMauiApp<App>()
    .UseLinux()
    .UseLinuxPdf();   // also makes Syncfusion's PdfToImageConverter render on Linux
  • SkiaPdfView shows a document's pages in a vertical or horizontal strip at 96 DPI times its zoom, rendered in the background at the screen's density: wheel, scrollbar and keys scroll, Ctrl+wheel and Ctrl +/-/0 zoom, and PageIndex/PageChanged follow the page in view. A library's PDF control maps onto it (MarketAlly.ViewEngine's PdfView does).
  • PdfiumDocument opens a PDF from bytes or a stream (with a password) and renders a page, or a region of it, to an SKBitmap or PNG, and reads its text.
  • With .UseLinuxPdf(), Syncfusion's PdfToImageConverter, whose platform-neutral build has no renderer, renders with PDFium at the Windows build's sizes, so SfPdfViewer works.

Optional: Maps (OpenStreetMap)

Microsoft.Maui.Controls.Maps on Linux uses the opt-in sibling package that adds an OSM raster-tile renderer:

dotnet add package Microsoft.Maui.Controls.Maps
dotnet add package OpenMaui.Controls.Linux.Maps

Then in your MauiProgram.cs:

builder
    .UseMauiApp<App>()
    .UseMauiMaps()
    .UseLinux()
    .UseLinuxMaps();   // Linux backend; no-op on Windows/Android/iOS/macCatalyst

Tiles are fetched on first view and cached under $XDG_CACHE_HOME/openmaui/osm-tiles.

Map.MapType selects the layer style:

  • Street — OpenStreetMap standard raster (© OpenStreetMap contributors).
  • Satellite — Esri "World Imagery" (keyless aerial basemap).
  • Hybrid — the satellite base with an Esri transparent labels/boundaries overlay.

The active layer's attribution is drawn in the on-map overlay. The Esri layers are keyless but governed by Esri's terms of use, not the OSM tile policy — confirm those terms for production use, or redirect the sources at your own imagery.

Each layer is a TileSource with a settable URL template (the {z}/{x}/{y} placeholder position sets the axis order — OSM uses {z}/{x}/{y}, ArcGIS uses {z}/{y}/{x}). To use a self-hosted or commercial tile server, redirect a layer at startup:

using Microsoft.Maui.Platform.Linux.Maps.Services;

MapTileLayers.Street.UrlTemplate = "https://my-tiles.example.com/{z}/{x}/{y}.png";
// (OsmTileService.Default.UrlTemplate still works as a shortcut for the Street layer.)

For code-first map UI without Microsoft.Maui.Controls.Maps, the package also exposes a standalone SkiaMap view that subclasses SkiaView:

using Microsoft.Maui.Platform.Linux.Maps.Views;

var map = new SkiaMap { CenterLatitude = 35.68, CenterLongitude = 139.65, ZoomLevel = 11 };
map.Pins.Add(new MapPin { Latitude = 35.68, Longitude = 139.65, Label = "Tokyo" });

OSM's tile usage policy requires displaying attribution; SkiaMap renders the credit overlay automatically (toggle with ShowAttribution).

WebView (WPE WebKit)

WebView renders through WPE WebKit 2.54+ when it is installed, composited in the Skia tree like any other control, in native Wayland/X11 mode. Without WPE the GTK-hosted WebKitGTK view is used (requires options.UseGtk = true). OPENMAUI_WEBVIEW=wpe|webkitgtk|auto overrides the choice. HybridWebView uses the same engine.

# Debian testing / sid (Debian 13 carries 2.48, which is too old)
sudo apt install libwpewebkit-2.0-1

# Fedora (not in the official repositories; maintained by an Igalia WPE developer)
sudo dnf copr enable philn/wpewebkit && sudo dnf install wpewebkit

Ubuntu has shipped no WPE WebKit package since 22.04, and Debian 13 only has 2.48. There, WebView uses the GTK-hosted WebKitGTK view (options.UseGtk = true), and BlazorWebView needs a WPE 2.54 installed from elsewhere. OPENMAUI_DOCTOR=1 ./MyApp reports which engine a machine will use.

Optional: Blazor Hybrid (BlazorWebView)

BlazorWebView on Linux uses the opt-in sibling package on top of the WPE WebView:

dotnet add package Microsoft.AspNetCore.Components.WebView.Maui
dotnet add package OpenMaui.Controls.Linux.Blazor
builder
    .UseMauiApp<App>()
    .UseLinux()
    .UseLinuxBlazorWebView();   // Blazor WebView services + WPE-backed handler; no-op off Linux

Use HostPage="wwwroot/index.html" and RootComponent exactly as on the other platforms; wwwroot is served from the app's output directory (the sample marks it CopyToOutputDirectory). External links open in the system browser through UrlLoading. See the BlazorDemo sample.

XAML Support

OpenMaui fully supports standard .NET MAUI XAML syntax. Use the familiar XAML workflow:


<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.MainPage">
    <VerticalStackLayout>
        <Label Text="Hello, OpenMaui!" FontSize="32" />
        <Button Text="Click me" Clicked="OnButtonClicked" />
        <Entry Placeholder="Enter text..." />
        <Slider Minimum="0" Maximum="100" />
    </VerticalStackLayout>
</ContentPage>
// MauiProgram.cs
var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    .UseLinux();  // Enable Linux with XAML support (auto-detects X11/Wayland)

Backend Selection (X11 / Wayland)

Pick exactly one — calls are no-ops on Windows/Android/iOS so they're safe in cross-platform MauiProgram.cs:

builder
    .UseMauiApp<App>()
    .UseLinux();      // auto-detect from session (default)
    // .UseX11();     // force X11/XWayland — most stable, recommended for WebView-heavy apps
    // .UseWayland(); // prefer native Wayland; auto-falls back to X11 if Wayland unavailable

Native Wayland uses xdg-shell + wp_viewporter for fractional-scale rendering and ssd via zxdg_decoration_manager_v1. The X11 path remains the default fallback and is fully supported. Environment overrides (MAUI_PREFER_X11=1, GDK_BACKEND=x11) still work and take effect before the builder runs.

Rendering (GPU / raster)

Frames are rasterised by Skia's OpenGL ES backend and presented through EGL: zero-copy eglSwapBuffers on native Wayland, DRI3/Present on X11. When EGL cannot be initialised (no libEGL, software-only drivers, headless CI) the platform falls back to the CPU raster path automatically, so an app always renders.

builder.UseLinux(options => options.Renderer = RendererPreference.Raster); // Auto (default) | Gpu | Raster

Environment overrides, useful for A/B checks and bug reports:

OPENMAUI_RENDERER=raster ./MyApp      # force the CPU path (gpu | raster | auto)
OPENMAUI_RENDER_STATS=1 ./MyApp       # print rendered FPS and avg/p50/p95/p99/max frame time every 2 s

The chosen renderer is logged at startup, e.g. Renderer: egl-wayland (EGL 1.5 Mesa Project; Mesa Intel(R) UHD Graphics). Measured on video playback at 1400x1050 on Mesa/Intel, the GPU path renders a frame in 1.47 ms average (p99 under 4 ms) against 3.55 ms (p99 7-10 ms) for raster.

Supported Controls

Category Controls
Basic Button, Label (incl. FormattedText), Entry, Editor, CheckBox, Switch, RadioButton, SearchBar
Layout StackLayout, Grid, FlexLayout, AbsoluteLayout, ScrollView, ContentView, Border, Frame, ControlTemplate / ContentPresenter / TemplatedView
Selection Picker, DatePicker, TimePicker, Slider, Stepper
Display Image (incl. FontImageSource), ImageButton, ActivityIndicator, ProgressBar
Collection CollectionView, ListView, TableView, CarouselView, IndicatorView
Gesture SwipeView, RefreshView; Tap, Pan, Pinch, Swipe, Pointer and Drag/Drop recognizers
Navigation NavigationPage, TabbedPage, FlyoutPage, Shell, modal pages
Dialogs DisplayAlert, DisplayActionSheet, DisplayPromptAsync
Menu MenuBar, MenuFlyout, context flyouts (FlyoutBase.ContextFlyout), MenuItem
Shapes Ellipse, Line, Rectangle, Polygon, Polyline, Path
Graphics GraphicsView, Border
Web WebView (WPE WebKit), HybridWebView, BlazorWebView

The measured picture is in docs/COMPATIBILITY.md: a scorecard generated from the test run (dotnet run --project tools/Scorecard -- --run) in the same categories Microsoft publishes for its maui-labs GTK backend. An item counts as covered only when every test mapped to it passed, so the percentages are computed, not claimed.

Platform Services

Service Description
ClipboardService System clipboard access
FilePickerService Native file open dialogs
FolderPickerService Folder selection dialogs
NotificationService Desktop notifications (libnotify)
GlobalHotkeyService System-wide keyboard shortcuts
DragDropService XDND drag and drop protocol
LauncherService Open URLs and files
ShareService Share content with other apps
SecureStorageService Encrypted credential storage
PreferencesService Application settings
BrowserService Open URLs in default browser
EmailService Compose emails
SystemTrayService System tray icons

Accessibility

  • AT-SPI2: Screen reader support for ORCA and other assistive technologies
  • High Contrast: Automatic detection and color palette support
  • Keyboard Navigation: Full keyboard accessibility

Requirements

  • .NET 10.0 SDK or later
  • Linux (kernel 5.4+)
  • X11 or Wayland
  • SkiaSharp native libraries

System Dependencies

Ubuntu/Debian:

sudo apt-get install libx11-dev libxrandr-dev libxcursor-dev libxi-dev libgl1-mesa-dev libfontconfig1-dev

Fedora:

sudo dnf install libX11-devel libXrandr-devel libXcursor-devel libXi-devel mesa-libGL-devel fontconfig-devel

Diagnosing your setup

Any OpenMaui app can print an environment report instead of starting. Set OPENMAUI_DOCTOR=1 (or pass --openmaui-doctor); the app writes the report to stdout and exits before creating a window, with exit code 1 when a required item is missing:

OPENMAUI_DOCTOR=1 ./MyApp
dotnet run -- --openmaui-doctor

The report runs inside the platform, so it shows what the app will actually select: display server and compositor, the Wayland globals it advertises, the EGL/GL renderer and the render target RenderTargetFactory will pick, the scale factor and which detection source won, the IME backend, and every optional native dependency and fallback font. Anything missing comes with the install command for your distro (apt, dnf or pacman). Trimmed output from a Fedora 44 KDE session on an Intel GPU:

OpenMaui doctor
===============

Runtime
  [ok]      .NET                         .NET 10.0.10 (X64, fedora.44-x64)
  [info]    OS                           Fedora Linux 44 (KDE Plasma Desktop Edition), kernel
                                         7.1.5-201.fc44.x86_64; install hints for: Fedora (dnf)

Wayland compositor
  [ok]      libopenmaui_wl.so            /home/me/MyApp/bin/Debug/net10.0/libopenmaui_wl.so
  [ok]      Compositor                   kwin_wayland_wr (pid 14908)
  [ok]      zwp_text_input_manager_v3    v2: native IME (zwp_text_input_v3)
  [ok]      zwp_linux_dmabuf_v1          v5: dmabuf buffer sharing

GPU and renderer
  [ok]      EGL                          EGL 1.5 Mesa Project (client APIs: OpenGL OpenGL_ES)
  [ok]      GL renderer                  Mesa Intel(R) UHD Graphics (CML GT2) (OpenGL ES 3.2 Mesa 26.1.5)
  [ok]      RenderTargetFactory          egl-wayland (GPU)

Display scale
  [info]    Startup scale                1.75 (168 dpi)
  [info]    Detected by                  HiDpiService: X11 (Xft.dpi / .Xresources / X server DPI)

Native dependencies
  [ok]      GStreamer                    libgstreamer-1.0.so.0, libgstapp-1.0.so.0: MediaElement playback
  [ok]      WPE WebKit 2.54+             libWPEWebKit-2.0.so.1: composited WebView / BlazorWebView
  [MISSING] libcups                      libcups.so.2 not found; printing unavailable
                                         fix: sudo dnf install cups-libs

Summary: 31 ok, 0 warning(s), 1 missing (0 required).

(The libcups row above is illustrative of how a missing dependency is shown.)

Checking your app's pages

Set OPENMAUI_INVARIANTS=1 and use the app: each page is checked a second after it appears (and every five seconds while it stays), and what is broken is printed to stderr. The rules hold for every MAUI page, so they catch whole classes of problems in OpenMaui or in the app without a test written for that page:

Rule Reports
type-name-text text that is a .NET type name (an object drawn through its ToString)
draws-outside-bounds an image or video that draws outside its frame
unreachable-control a visible, enabled control that a click at its centre does not reach
clipped-text a label shorter than its text, or reaching past the bottom or top of a view around it (a row cut too short); a truncating LineBreakMode or MaxLines, and content inside a scrolling view, are not reported
binding-failed a binding that failed (MAUI's binding diagnostics are turned on for this)
error-logged an error OpenMaui logged while the page was shown
[Invariant] checked LibraryPage: 0 violation(s)
[Invariant] checked EconomyPage: 1 violation(s)
[Invariant] binding-failed: 'IsOffline' property not found on 'EconomyViewModel', target property: 'ChatPane.IsOffline' (binding)

Documentation

Sample Applications

Full sample applications are available in the maui-linux-samples repository:

Sample Description
TodoApp Task manager with NavigationPage, XAML data binding, CollectionView
ShellDemo Control showcase with Shell navigation and flyout menu
WebViewDemo Web browser with WebView (WPE WebKit in native mode), navigation controls, and XAML UI
BlazorDemo Blazor Hybrid: BlazorWebView with Razor components, counter, two-way binding, DI-injected service, external links via UrlLoading
MediaDemo Video/audio player with CommunityToolkit.Maui.MediaElement on Linux (GStreamer backend); play/pause/seek/volume/mute, HTTP streams and local files
MapsDemo OpenStreetMap map view with Microsoft.Maui.Controls.Maps on Linux; pins, route polyline, pan/zoom, cached OSM raster tiles

Distribution

Package your OpenMaui app as a portable AppImage with a single command:

dotnet tool install --global OpenMaui.AppImage
openmaui-appimage --project ./MyApp

Publishes the project, auto-detects the executable and icon, generates the .desktop file and installer, and produces a self-contained AppImage that runs on most Linux distributions. Full reference (options, CI recipes, host-dependency checks, signing, self-update): OpenMaui.AppImage packaging guide — written to be followed verbatim by humans or AI assistants.

Quick Example

// MauiProgram.cs
using Microsoft.Maui.Hosting;
using Microsoft.Maui.Platform.Linux.Hosting;

var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    .UseLinux();   // or .UseX11() / .UseWayland() to force a backend

var app = builder.Build();
LinuxApplication.Run(app, args);

Building from Source

# Primary repository
git clone https://git.marketally.com/open-maui/maui-linux.git

# Or from the GitHub mirror
git clone https://github.com/open-maui/maui-linux.git

cd maui-linux
dotnet build
dotnet test tests/OpenMaui.Controls.Linux.Tests.csproj
dotnet test tests/Compat/OpenMaui.Compat.Tests.csproj   # third-party libraries

The suite runs serially (the platform has process-wide state) and needs no display: golden-screenshot scenes render offscreen through the real engine at 1.0x to 2.0x (OPENMAUI_UPDATE_GOLDENS=1 re-records baselines after an intended change), and the WebView scenarios run in a small out-of-process host because WebKit binds itself to the process main thread. Regenerate the scorecard with dotnet run --project tools/Scorecard -- --run, which runs both suites.

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Note: Please submit issues and pull requests on GitHub.

Architecture

┌─────────────────────────────────────────────────┐
│                  .NET MAUI                       │
│              (Virtual Views)                     │
├─────────────────────────────────────────────────┤
│                  Handlers                        │
│         (Platform Abstraction)                   │
├─────────────────────────────────────────────────┤
│              Skia Views                          │
│        (SkiaButton, SkiaLabel, etc.)            │
├─────────────────────────────────────────────────┤
│           SkiaSharp Rendering                    │
│         (Hardware Accelerated)                   │
├─────────────────────────────────────────────────┤
│              X11 / Wayland                       │
│          (Display Server)                        │
└─────────────────────────────────────────────────┘

Styling and Data Binding

OpenMaui supports the full MAUI styling and data binding infrastructure:

XAML Styles

<ContentPage.Resources>
    <ResourceDictionary>
        <Color x:Key="PrimaryColor">#5C6BC0</Color>
        <Style TargetType="Button">
            <Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
            <Setter Property="TextColor" Value="White" />
        </Style>
    </ResourceDictionary>
</ContentPage.Resources>

Data Binding

<Label Text="{Binding Title}" />
<Entry Text="{Binding Username, Mode=TwoWay}" />
<Button Command="{Binding SaveCommand}" IsEnabled="{Binding CanSave}" />

Visual State Manager

All interactive controls support VSM states: Normal, PointerOver, Pressed, Focused, Disabled.

<Button Text="Hover Me">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal">
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="#2196F3"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="PointerOver">
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="#42A5F5"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Button>

License

Copyright (c) 2025-2026 MarketAlly Pte Ltd. Licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • MarketAlly Pte Ltd - Project development and maintenance
  • SkiaSharp - 2D graphics library
  • .NET MAUI - Cross-platform UI framework
  • PDFium - PDF rendering in OpenMaui.Controls.Linux.Pdf (Apache-2.0), packaged by bblanchon/pdfium-binaries
  • The .NET community
  • A very special thank you to the Anthropic team for delivering on the promise I hold most dear — that an individual with enough energy and persistence can still make a difference
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.110.7 0 10/4/2026
10.0.110.6 53 10/1/2026
10.0.110.5 87 9/28/2026
10.0.110.4 96 9/28/2026
10.0.110.3 88 9/27/2026
10.0.110.2 96 9/27/2026
10.0.110.1 90 9/27/2026
10.0.101.3 96 9/20/2026
10.0.101.2 107 9/20/2026

OpenMaui 10.0.110.7:
- A gate on MAUI's handler mappings
- Geolocation listens
- `Battery.EnergySaverStatus` follows the desktop's power profile
- Layouts run MAUI's own layout managers
- A Windows-vs-Linux layout comparison
- dotnet/maui's own handler tests run against the Linux handlers
- The input method learns each field's content type
- Images load through MAUI's image-source services
- Page checks for any app
- Tests and parity gates run in CI, in their own workflow
- Third-party stub scan
- dotnet/maui's Controls device tests run against OpenMaui
- `ShapeViewHandler` and `RoundRectangleHandler`
- Shell shows its bottom tab bar
- `Shell.TitleView`
- `Window.Toolbar` has a Linux `ToolbarHandler`
- `CoreSwipeViewHandler` and `SwipeItemViewHandler`
- Handlers for MAUI's core interfaces
- `VisualElement.CaptureAsync()` and `Window.CaptureAsync()` return an image
- `Window.DisplayDensity`
- dotnet/maui's Essentials device tests run against OpenMaui
- Geocoding works on Linux, opt-in
- HybridWebView works on Linux
- `WebKitContentApi`
- CollectionView `CanReorderItems`
- CarouselView
- Motion and environment sensors
- `MediaPicker.CapturePhotoAsync` and `CaptureVideoAsync`
- Contacts
- CommunityToolkit TouchBehavior and ImageTouchBehavior
- CommunityToolkit Toast and Snackbar
- CommunityToolkit `Badge.SetCount`
- CommunityToolkit DrawingView
- NavigationPage bar
- Window overlays
- `Window.TitleBar`
- Pickers `IsOpen`
- Tab and Shift+Tab move keyboard focus
- Syncfusion SfNumericEntry
- Syncfusion SfComboBox and SfAutocomplete
- Syncfusion, smaller
- MediaElement behaves as on Windows
- MediaElement `ShouldShowPlaybackControls`
- MediaElement metadata over MPRIS
- Syncfusion SfDataGrid works with a mouse and keyboard, as on Windows
- Syncfusion SfImageEditor edits images
- Syncfusion SfScheduler with a mouse
- Resize and move cursors
- Syncfusion SfToolbar with a mouse and keyboard, as on Windows
- Syncfusion SfScheduler resource view, as on Windows and Mac
- A Button with a truncating `LineBreakMode` did not truncate
- A Button with `LineBreakMode` `WordWrap` or `CharacterWrap` drew one line
- `AppInfo.RequestedLayoutDirection` was always left-to-right
- `Email.IsComposeSupported`, `Sms.IsComposeSupported` and `PhoneDialer.IsSupported` were always true
- Changing `CheckBox.Color` after the box was shown did not recolour it
- A ScrollView measured with unbounded room took a made-up 400 px
- MediaElement measured 0 x 0 in a MAUI layout
- A library control with its own `MeasureOverride` was measured twice per layout pass
- Opacity, Visibility, FlowDirection, AutomationId, semantics, InputTransparent and ZIndex reach the platform view through the handler
- A Button whose handler is the plain `ButtonHandler` showed no text
- RadioButton used only the font size
- Picker, DatePicker and TimePicker ignored italic
- Image and ImageButton raised none of MAUI's image loading notifications
- Disconnecting a layout handler left its platform children attached
- Entry, Editor and SearchBar ignored `Keyboard`
- `MaxLength` only limited typing
- An app's null `Text` was overwritten with ""
- SearchBar lacked most text-input properties
- Focus did not reach `IsFocused`
- A CollectionView's Header and Footer were drawn as text in fixed bands
- Every CollectionView row (and CarouselView page, and Shell flyout row) first bound to the page's view model
- NavigationPage
- TabbedPage and FlyoutPage
- Shell
- Windows
- Label
- Entry and Editor
- A view's desired size could exceed the space it was offered
- Smaller
- Polygon and Polyline did not redraw when a point was added to `Points`
- `VisualTreeElementExtensions` found nothing on Linux
- Label
- `AutomationProperties.ExcludedWithChildren` was ignored
- `Window.Width`, `Height` and `SizeChanged` never worked in a single-window app
- Shell
- TabbedPage
- A page with a CollectionView was never released after it closed
- `CollectionView.ScrollTo` did nothing
- `CollectionView.IsGrouped` was ignored
- A horizontal CollectionView was drawn as a vertical list
- CarouselView did not show items added after it appeared
- A SwipeView row was cut to 44 px
- ScrollView content lost its alignment on the next frame
- A handler connected through MAUI's own API
- SwipeView behaves as on the other platforms
- A window without a native display (embedded, or under test) ignored `Window.Width`, `Height`, `X` and `Y`
- Wrapped label text took the whole width offered
- Clicking an IndicatorView dot did not change `Position`
- Tooltips
- Arranging a view runs the `IView.Frame` command
- `Permissions` threw for every permission
- `FileResult.OpenReadAsync`, `ContentType` and the `FileBase` copy constructor threw
- `AppInfo` ignored the project's `ApplicationTitle`, `ApplicationId`, `ApplicationDisplayVersion` and `ApplicationVersion`
- SecureStorage was shared by every app
- `VersionTracking`
- `Launcher.CanOpenAsync` and `TryOpenAsync`
- Essentials details
- Every collection change rebuilt a CollectionView and sent it back to the top
- A horizontal `GridItemsLayout` was drawn as a vertical grid
- CollectionView
- CarouselView
- MediaPicker
- CommunityToolkit SpeechToText and OfflineSpeechToText
- Layouts exposed no children to screen readers
- A ContentView, TitleBar, SwipeView or NavigationPage lost its `BackgroundColor` when it got its handler
- SfTextInputLayout drew the inner Entry's or Editor's own box
- A selection set from code on an Entry
- MediaElement
- `RotationX` and `RotationY` were ignored
- A hang drawing Syncfusion text into a strip narrower than one character
- The content of a CollectionView or ListView row got no pointer events
- An Expander expanding in a CollectionView with a `GridItemsLayout`
- Syncfusion toolbar tool tips never showed
- Syncfusion SfDataGrid
- Syncfusion SfComboBox and SfAutocomplete measure as on Windows
- Syncfusion stamp annotations
- A layout that handles a press itself stopped receiving pointer moves outside its bounds

Full changelog: https://github.com/open-maui/maui-linux/blob/main/CHANGELOG.md