Skip to content

About

Rustolonia - Avalonia in Rust

Topics

Resources

Contributing

Security policy

Stars

19 stars

Watchers

0 watching

Forks

Latest commit

 

History

57 Commits

Folders and files

Repository files navigation

rustolonia

First-class Rust bindings for Avalonia, projected over a nano-COM ABI served by a NativeAOT host. This repository contains the complete bindings effort; the Avalonia framework itself is consumed from the pinned avalonia-src producer submodule at upstream Avalonia 12.1.6 (commit cf8e564674700348947e93ab19105f27afe859a9).

Layout

Directory Contents
avalonia-src/ Avalonia producer pinned to the upstream 12.1.6 tag (cf8e564674700348947e93ab19105f27afe859a9), cloned from AvaloniaUI/Avalonia
avalonia-patches/ Additive framework patches applied onto the pinned checkout (see its README + UPSTREAM.md)
rust/ The Rust workspace: rustolonia (safe bindings), rustolonia-macros (rsx!, #[component], #[derive(Lens)], color!, tracks!, fmt!), rustolonia-sys (ABI bindings), rustolonia-bindgen (IR to Rust generator), rustolonia-apk (Cargo-only Android APK packager), avalonia-sample (flagship sample's application-owned view-model API), templates, build scripts, and the checked-in IR
host/ Avalonia.Host - the C# NativeAOT host that serves the ABI, plus its generated object model
projection/ The projection pipeline: IR extraction, C#/header emitters, and the generator tools
interop/ Avalonia.Rust and Avalonia.Rust.Interop - the managed-side view-model interop layer
apps/system-monitor/ NeoHtop, a real Rust-owned system monitor with compiled AXAML presentation and a packaged NativeAOT host
apps/pdf-viewer/ A PDF Oxide-powered sample viewer with rendered page navigation and extracted text
apps/hash-calculator/ A streaming checksum utility (MD5, SHA-1, SHA-256, SHA-512, BLAKE3) with compare and copy
apps/archive-tool/ A dual-pane archive manager (zip/tar/7z/cab and compressed tars)
apps/android-hello/ A code-first app that runs as an Android APK and on the desktop from one UI module (see rust/PLATFORMS.md)
templates/ Copy-out standalone app skeletons using the published bindings and prebuilt host
tests/ Host, IR, and generator test suites
samples/ RustViewModelSample.Managed - the sample presentation project the host consumes
build/ Vendored MSBuild configuration (versioning, signing, analyzers, xunit)

Quick start (GitHub release)

Code-first applications using the default shared host need only Cargo; no .NET SDK or source checkout:

[dependencies]
rustolonia = { git = "https://github.com/Devolutions/rustolonia", tag = "v12.1.0" }

Use the final v12.1.0 tag once its GitHub release is published. Cargo finds the crate in the rust/ workspace and resolves rustolonia-sys from the same git revision; no crates.io publication or [patch.crates-io] is needed. Rust 1.88 or newer is required. Version 12.1.0 is the first Rustolonia release, backed by Avalonia 12.1.3. The major/minor identify the Avalonia line; the patch counts Rustolonia releases independently and does not identify the upstream patch. This checkout prepares Rustolonia 12.1.6 against Avalonia 12.1.6; the matching patch numbers are coincidental. Applications using this checkout need a locally built host until the matching release artifacts and checksums are published.

On the first build, rustolonia-sys downloads the prebuilt NativeAOT host for your target (Windows, macOS and Linux glibc, x64 and arm64) from the matching GitHub release, verifies its SHA-256, and caches it. See rust/rustolonia/README.md for a hello-world and how to ship the host with your application, and rust/rustolonia-sys/README.md for offline, mirrored and locally built hosts.

For a fully static Linux X11 executable, releases containing the separate musl hosts support the static-host feature and a matching musl Rust toolchain; see fully static Linux builds. Existing releases do not yet include these assets. Static hosts on macOS and Windows still depend on operating-system libraries.

Applications with compiled AXAML and Rust view-models still build their own host from a source checkout, as described below.

Experimental embedded Linux support selects direct DRM/KMS with the Cargo feature linux-drm, using separate prebuilt hosts in releases containing this feature. Existing releases do not include DRM assets. Source builds use -LinuxBackend Drm. It renders one fullscreen view directly through DRM/KMS without X11; see embedded Linux setup.

Code-first apps for iOS, Android and the browser can also be built without .NET tooling, from prebuilt hosts published with releases from the first one that includes them, each verified against host-checksums.txt:

Platform Prebuilt host Tools needed Start from
iOS (experimental) rustolonia-host-<v>-ios*.tar.gz (NativeAOT objects) Rust, Xcode samples/ios-standalone
Android rustolonia-host-<v>-android.apk Rust, Android NDK cargo rustolonia-apk (rust/PLATFORMS.md)
Browser rustolonia-host-<v>-browser-wasm.tar.gz (relink kit) Rust, Emscripten SDK 3.1.56 samples/browser-standalone

None of these use the desktop host discovery mechanism. The source-built iOS sample, rust/build-android.ps1 and rust/build-browser.ps1 build the hosts locally instead.

For standalone starting points, see the app templates: code-first apps use a released host, while the Rust-only AXAML template currently needs this Rustolonia source revision.

After the crates are published to crates.io, rustolonia = "=12.1.0" is an alternative to the git dependency.

Getting started

git clone --recurse-submodules https://github.com/Devolutions/rustolonia
cd rustolonia
pwsh ./avalonia-patches/apply-avalonia-patches.ps1 -AvaloniaRoot ./avalonia-src
pwsh ./rust/regenerate-and-build.ps1 -Configuration Release

The regeneration pipeline (IR, generated C#, native header, Rust bindings, and the standalone AXAML template's projection catalog) is deterministic; CI fails if regenerating changes the checkout. Generated outputs have checked-in ownership manifests so stale cleanup does not erase another generator's files. Generator CLIs also provide non-mutating --check modes.

Open Rustolonia.slnx for the managed projects. See CONTRIBUTING.md for the contributor workflow and code-generation boundaries.

Creating a new app

For a standalone code-first app, copy one of the code-first root templates/ outside this repository and run cargo run --locked from the copied directory. They need no .NET SDK or local source checkout.

For AXAML authoring without .NET, start from the Rust-only AXAML template. It transpiles supported markup to Rust during Cargo builds and uses a matching prebuilt host; it is not full Avalonia AXAML compatibility. Until a release includes the new APIs, the template must point to a checkout of this Rustolonia revision as described in its README. Neither the app build nor the checkout requires a .NET SDK.

For compiled AXAML and generated Rust view-models, use the source-build scaffold:

pwsh ./rust/new-app.ps1 -Name my_app -Destination ../my_app -ProducerRoot ./avalonia-src -RustoloniaRoot .
pwsh ./rust/build-app.ps1 -ProducerRoot ./avalonia-src -Manifest ../my_app/avalonia-app.json -UpdateLockFile

The generated app keeps the producer root and Rustolonia root separate, allows paths with spaces, and validates the declared roots before writing any files. References are relative when the checkouts share a volume; the manifest defaults to the current OS/architecture and global.json pins the supported SDK policy. Commit Cargo.lock after the first build and omit -UpdateLockFile thereafter. Normal builds require matching producer revisions/applied patches and initialized submodules, run Cargo locked, and never format handwritten Rust.

The in-repository system monitor uses the same consumer path without a vendored checkout:

pwsh ./apps/system-monitor/build.ps1

CI

.github/workflows/avalonia-rust.yml keeps the native release and cross-build gates running automatically on pull requests and pushes to master. Native execution covers Windows/Linux x64 and macOS x64/arm64; Windows/Linux arm64 have cross-build packaging coverage, not native execution coverage. The original flagship samples remain part of the release gate. Pull requests run a fast tier; a newer push cancels the in-flight PR run. Pushes to master and manual runs add the Windows/macOS external-consumer builds, the system monitor, the packaged sample bundles, the source-integrated iOS simulator sample, and the unsigned iOS device build. On pull requests the iOS job builds the packaged simulator host and runs the Rust-only consumer against it. Artifacts are named avalonia-rust-native-<rid> for native jobs and avalonia-rust-cross-<rid> for cross-build jobs, so their provenance remains unambiguous when both jobs target the same RID.

The quick helper/scaffold suite does not build or launch an application:

pwsh ./rust/tests/test-build-app.ps1

Native jobs additionally build and launch a fresh external consumer (Linux on every run; Windows and macOS outside pull requests):

pwsh ./rust/tests/test-build-app.ps1 -RunNativeSmoke

Linux native smoke execution needs a display, for example xvfb-run -a pwsh ./rust/tests/test-build-app.ps1 -RunNativeSmoke.

Native jobs also archive their host as a release tarball and build and launch a standalone app that depends on the packaged crates through the rustolonia-sys download path (rust/tests/test-standalone-app.ps1). .github/workflows/release.yml builds the release host tarballs from master into staged Actions artifacts, publishes a non-draft GitHub release on the checksum-bearing v* tag by default (draft=true opts into a draft), and optionally publishes the crates; see rust/PRODUCTIZATION.md.

About

Rustolonia - Avalonia in Rust

Topics

Resources

Contributing

Security policy

Stars

19 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages