New · Slint MCP server + llms.txt — build native UIs with Cursor, Claude Code & Copilot

June 16, 2026 · Slint Developers

DRAFT: Slint 1.17 ReleasedRSS

DRAFT -- this post is not final. Screenshots, the discussion id, the exact release date, and the contributor list still need to be filled in.

We're happy to announce Slint 1.17. Slint is a toolkit written in Rust -- with APIs for Rust, C++, JavaScript, and Python -- for building native user interfaces for desktop, embedded, and mobile applications.

Making Slint Desktop-Ready

Back in November we laid out a plan to make Slint desktop-ready. With 1.17 we're ticking four more boxes from that list:

On top of that, we're shipping a remote preview mode for the viewer, an MCP server that lets AI assistants drive a running Slint application, a much faster Node.js integration, and the long-awaited cross-axis alignment on layouts.

Drag and Drop

Drag and drop is now a stable part of the language. A DragArea marks the source of a drag, a DropArea marks the target, and the payload is an opaque data-transfer value that you construct and read in your host language -- the same abstraction the platform uses for clipboard and inter-application transfers.

export global Api {
    pure callback make-transfer(string) -> data-transfer;
    pure callback read-transfer(data-transfer) -> string;
}

export component Example inherits Window {
    DragArea {
        data: Api.make-transfer("Hello World");
        preferred-action: DragAction.copy;
        Rectangle { background: #f0c000; width: 100px; height: 100px; }
    }

    drop := DropArea {
        x: 150px;
        can-drop(event) => DragAction.copy;
        dropped(event) => {
            debug("Got: ", Api.read-transfer(event.data));
            return event.proposed-action;
        }
        Rectangle {
            background: drop.contains-drag ? #80e080 : #a0a0a0;
            width: 100px;
            height: 100px;
        }
    }
}

can-drop runs while the drag hovers and returns a DragAction (copy, move, link, or none) that drives the cursor and any visual feedback; dropped runs on release and confirms the action. A DragArea declares which actions it allows and reacts to the result through drag-finished, so a "move" source can remove the original data once the drop completes. See the drag and drop guide for the full picture.

A DropArea also accepts drops coming from other applications on the platforms where the OS supports it. What doesn't work yet is the reverse direction: starting a drag inside a Slint window and dropping it into another window or application. That needs support we don't yet have in the underlying windowing layer. We've prepared patches for winit that add it, but they're still awaiting upstream review and will need a new winit release before they can reach Slint. Our work on popup windows and modal dialogs is in the same position -- the design is ready, but it also depends on winit changes that haven't merged yet.

System Tray Icons

Run a quiet background app, surface a status, or expose a quick-action menu from the system tray with the new SystemTrayIcon element:

import { SystemTrayIcon } from "std-widgets.slint";

export component App inherits Window {
    SystemTrayIcon {
        icon: @image-url("tray.png");
        tooltip: "My App";
        activated => { root.show(); }
    }
}

Tooltips and Radio Groups

Two new widgets that show up everywhere in a real desktop app.

Add a tooltip to any element with the new ToolTip element:

Button {
    text: "Save";
    ToolTip { text: "Save the current document (Ctrl+S)"; }
}

And bundle a set of radio buttons with RadioGroup, which manages selection and keyboard navigation for you:

RadioGroup {
    model: ["Small", "Medium", "Large"];
    current-index: 1;
}

Two-Way Bindings on Model Rows

Slint 1.15 added two-way bindings on struct fields. 1.17 closes the loop with two-way bindings on model row data, so you can edit a row in place without bouncing through a callback to write the change back:

for item[i] in model: LineEdit {
    text <=> item.name;
}

Cross-Axis Alignment on Layouts

VerticalLayout and HorizontalLayout finally gained an align-items property for aligning children along the cross axis (#2587).

HorizontalLayout {
    align-items: center;
    Text { text: "Label"; }
    LineEdit { }
}

Remote Slint Viewer

The Slint viewer already gives you a live preview of a .slint file outside of an editor. With 1.17, slint-viewer learned a --remote flag: it connects to a Slint LSP running on another machine and renders the design locally. Together with the new builds of the viewer for iOS and Android, you can edit a .slint file on your desktop and watch the result on a phone or tablet as you type.

A Faster Node.js Port

Two of the biggest blockers for the Node.js port were a polling event loop and a callback leak. 1.17 addresses both.

On Linux and macOS, Slint now integrates its event loop with the libuv file descriptor that Node uses, removing the polling we relied on previously and dropping CPU usage to near zero when the app is idle. We've also fixed a leak that kept component instances alive when a callback handler held a reference back to them.

The libuv integration isn't in place on Windows yet.

MCP Server and Skills for AI Assistants

The Slint LSP now ships a Model Context Protocol server, together with a set of skills that teach AI coding assistants how to work with Slint projects. Once connected, an assistant can:

  • Inspect a running Slint application through its accessibility tree -- the same view a screen reader gets.
  • Drive the UI by injecting mouse clicks, touch events, and keyboard input, using the same plumbing as our test driver.
  • Capture screenshots to see what's actually on screen and reason about the result of an interaction.

Because it's built on top of the accessibility and testing APIs we already had, an assistant sees exactly what an automated test or a screen reader sees, no special debugging hooks required.

And More ...

A few smaller items worth calling out:

  • C++ on Android. You can now build Slint apps for Android from a C++ codebase. See the C++ Android guide to get started.
  • Custom title bars. The Window element gained minimized, maximized, close(), and hide(), which are what you need to wire up a custom title bar. Platform.bring-all-to-front() brings every window of a multi-window app forward at once.
  • Markdown parsing in native code. The StyledText API in Rust, C++, JavaScript, and Python now parses markdown at runtime, so you can construct styled text from data your app loads at runtime, not just from .slint literals.
  • Rust: render into external WGPU textures. A new slint::platform::skia_renderer::SkiaWGPURenderer lets you embed Slint into a WGPU-driven application, alongside the existing FemtoVGWGPURenderer.
  • Drop-shadow improvements. Rectangle gained drop-shadow-spread and a full set of inset-shadow-* properties (Skia only).
  • Flickable polish. Wheel scrolling animates, tab focus no longer skips items, and double-click text selection works inside a Flickable.
  • ListView polish. Items with differing heights now behave reliably, including during drag-and-drop reordering.
  • TextInput now shows a caret and allows selection in read-only fields.
  • iOS detects the system dark/light theme.

For the full picture, see the ChangeLog.

Getting Started with Slint 1.17

Don't forget to star us on GitHub, join our Mattermost chat, and share your projects.

Thanks

Big thanks to everyone who contributed code, fixes, or feedback. You help us make Slint better with every release.

Join the discussion Slint is a Rust-based toolkit for reactive, fluent user interfaces across embedded, desktop, mobile and web — one declarative language that compiles to native code, with business logic in Rust, C++, JavaScript or Python.