Material 3 Expressive,
running in Slint.

A working spike in bringing expressive shapes, spring motion, and Material components to a native UI toolkit.

An independent experiment in a Slint fork. The spike works; the library is still being completed.

The question

Can Material 3 Expressive feel at home in Slint?

That means more than matching a button’s color. Shapes change as you press them. Springs carry movement between states. Type, elevation, focus, and touch targets all have to agree.

This started as a port of Material components and grew into an experiment across the library, the Slint runtime, and its renderers.

A real app makes the differences visible

Fieldnotes is a small day planner built from the port: task editing, completion filters, responsive navigation, light and dark colors, and reduced motion.

Putting components together exposed problems isolated samples missed: app bars stretching in layouts, clipped tooltips, dialog dismissal state, and a slow desktop preview.

The useful test is a complete interaction: open the editor, type a task, save it, filter it, and edit it again.

Those interactions now have regression checks. Fieldnotes keeps its tasks in memory while the window is open.

Meet Fieldnotes

Actual renders from the Slint application.

Open the full image
Fieldnotes in light colors, showing a navigation rail, completion filters, and a list of editable tasks.
A navigation rail on a wide window, with task filters and an editor one click away.
Fieldnotes in a narrow light window, with wrapped task notes and bottom navigation.
A smaller window. Bottom navigation replaces the rail; task notes wrap.
The same narrow Fieldnotes layout in dark colors.
A different palette. The same components follow the dark theme.
Fieldnotes task editor showing the required task-name field and its validation message.
A complete workflow. Task editing includes validation, keyboard save, and dismissal.

Motion is part of the interface

Compare the task editor with reduced motion off and on.

Reduced motion off. The scrim and editor fade into view.
Reduced motion on. The editor appears without the opacity transition.

These clips contain actual Slint-rendered frames sampled at a controlled 60 Hz clock. They demonstrate animation behavior, not measured GPU performance.

What it takes to make M3E work

The declarative components are one layer. The port also needs the machinery beneath them to reproduce the reference behavior.

Tokens tied to a reference
Generators translate the pinned AndroidX Material3 definitions into Slint colors, typography, shapes, and component values. Drift checks keep generated output reproducible.
Springs and changing shapes
The fork has spring easing and expressive shape support. Components use the active motion scheme for press, selection, expansion, and settling behavior.
Type and elevation
Variable fonts, baseline metrics, and Material elevation need to stay consistent with the component geometry. The parity harness checks geometry and motion as well as pixels.
Composition and overlays
A correct component still has to survive a real layout. This spike fixes app-bar sizing, pinned-bar tooltip clipping, and dialog dismissal callbacks. Other clipped containers still need an overlay solution.
The right desktop renderer
The original interactive preview used a debug build and CPU software rendering. Switching to an optimized Skia build over Direct3D 12 made it visibly smoother on the test machine.
Evidence across renderers
The same scenes are compared with a pinned Compose reference on software, Skia, and FemtoVG. Known differences remain explicit rather than disappearing behind a passing test count.

Read the preview report and verification details.

Where the spike ends

The working app establishes that the approach is viable. Full library completion is still a separate body of work.

Recorded inventory at the reviewed spike, October 10, 2026
StatusEntriesMeaning
Done61Recorded as matching the pinned specification; still subject to the completion audit.
Partial72Components exist, with API, interaction, motion, or rendering work remaining.
Missing17Includes carousel, wavy progress, drawer-sheet APIs, toggle names, and text-style helpers.

The inventory includes variants and Compose functions, not just distinct widgets. This table preserves the reviewed spike; the live inventory changes as the audit progresses.

The baseline covers 264 scenes across three Slint renderers. It includes deliberate negative cases and expected failures, so a green harness is not a claim of complete visual parity.

Remaining work includes completing the inventory, resolving implementation failures, validating native accessibility, and measuring representative interactions in release GPU builds.

Explore the full parity inventory.

Follow the work

The reviewed spike lives on the preview branch in jethac/slint.

cargo run --release \
  --manifest-path ui-libraries/material/Cargo.toml \
  -p material-fieldnotes

On Windows, Fieldnotes selects Skia and requires Direct3D 12. Software rendering remains useful for deterministic headless checks.

Upstream work

No upstream pull requests have been filed for this spike. Links and their status will appear here when that work starts.

Current work is committed to the fork. Upstream submission is a future step.