September 3, 2025 by Slint Developers

Slint 1.13 Released with Live-Preview for Rust and C++ Blog RSS


We're proud to announce the release of Slint 1.13. We're bringing live-preview into the Rust and C++ development cycle, extending the side panels of the live-preview with an interactive outline, and adding several quality-of-life improvements to the Slint language.

Let's take a closer look.

Live-Preview for Rust and C++

For years, Slint has offered a live-preview feature in our IDE plugins: Instantly see changes in the preview window as you edit .slint files. In contrast, when you compile your Rust or C++ application, the Slint compiler generates code thats linked with the application. A change to the .slint files requires re-building, re-linking, and restarting the application.

In this release, we're introducing live-preview for Rust and C++: Enable this feature in your build system, start the application, make changes to the .slint files, and save them in your editor. See how your UI updates without restart, as the Slint run-time library detects the changes automatically.

Set the SLINT_LIVE_PREVIEW=1 environment variable at compile time and either enable the slint/live-preview Cargo feature (Rust) or the SLINT_LIVE_PREVIEW CMake option (C++).

Behind the scenes, the Slint compiler replaces the native code generation for .slint files with stubs that have the same API. These stubs watch the file system for changes to the .slint files and reload them when necessary. This has a nice side-effect of reduced compilation times. When reloading, any properties, models, or callbacks that you've set are preserved, thus making it transparent to the application logic.

Live-Preview with a running Rust application

Updated Side Panels with Outline

We've reorganized the side panels in the live-preview and added the new Outline panel. It shows a tree view of selectable elements, where you can drag and drop to re-order, either within the outline or straight to the canvas.

Screenshot of a the new outline side panel

We've also added undo and redo for any changes you've made in the live-preview UI.

Improvements to the Slint Language

This release brings several improvements to the Slint language, many of which are valued community contributions.

Local Variables

Complex UIs tend to also require complex expressions. To make expressions or functions in Slint code easier to read and maintain, we've added support for local variables. Declare them using let within callbacks, functions, or binding expressions.

This replaces a common pattern where you'd declare properties and treat them like local variables. But these properties had a wider scope and may have resulted in accidental use in other parts of your code.

Here's a snippet from our dial example with let:

...
pointer-event(event) => {
    let newAngle = AppState.normalizeAngle(...);
    if event.kind == PointerEventKind.down {
        if hovering {
            lastAngle = newAngle;
        }
    } else if event.kind == PointerEventKind.move {
        if touching {
            nextAngle = AppState.normalizeAngle(...);
            if nextAngle >= AppState.startAngle
               || nextAngle <= AppState.endAngle {
                AppState.angle = nextAngle;
            }
            lastAngle = newAngle;
        }
    }
}

Intercepting Key Events

Key events are delivered to the focused element, and if not accepted, bubble up to the parent elements. In this release, we're introducing a new capturing phase before the bubbling phase: Use FocusScope's new capture-key-pressed and capture-key-released to intercept key events on their way from the Window to the focused element.

For example, this can be used to add arrow up/down navigation around LineEdit:

FocusScope {
  VerticalBox {
      search := LineEdit {
          placeholder-text: "search";
          edited(text) => {
              root.filter_model(text);
          }
      }
      list := StandardListView {
          current-item: 0;
          model: root.model;
      }
  }

  // This is invoked before the LineEdit child receives the key-pressed event.
  capture-key-pressed(event) => {
      if event.text == Key.UpArrow {
          list.current-item = max(list.current-item - 1, 0);
          return accept;
      }
      if event.text == Key.DownArrow {
          list.current-item = min(list.current-item + 1, list.model.length - 1);
          return accept;
      }
      reject
  }
}

Timer's new helper functions

The Timer component had a minimal API with a single running property. For improved usability we've added explicit helper functions to start(), stop(), and restart().

More Syntactic Sugar

For callbacks or change handlers with a single expression, the braces are now optional:

    clicked => { Logic.do-stuff(); } // old way
    clicked => Logic.do-stuff(); // new way works, too

Conic Gradients

Joining the linear and radial gradient party is the new @conic-gradient macro. It enables a range of visual effects, from simple pie charts to complex color wheels.

Screenshot of a conic gradient

πŸ› οΈ Other Fixes and Improvements

But wait, there's more:

  • Menu items can now be made checkable and use icons. On Windows, context menus now have a native look and feel.
  • The Slint software renderer supports radial gradients (thanks Tasuku).
  • Python: slint.Image can now be created from a buffer.
  • Python: Added support for enums.
  • C++: Fixed Windows ARM64 support.
  • Improved Rust compilation times by not generating code that would produce suppressed lints (#8966).

For a complete list of all changes, check out the full ChangeLog.

πŸš€ Getting Started with Slint 1.13

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.

@0x6e @asuper0 @AtlasRW @badicsalex @Be-ing @bluebear94 @cetra3 @codeshaunted @dfaure @georgik @gustavo-hms @kilavvy @leopardracer @loss-and-quick @meyer-mcmains @Montel @npwoods @panekj @petiaccja @redstrate @task-jp @ubruhin @VarinThakur @woile @xb284524239 @xunicatt @YohDeadfall


Comments

Slint is a Rust-based toolkit for creating reactive and fluent user interfaces across a range of targets, from embedded devices with limited resources to powerful mobile devices and desktop machines. Supporting Android, Windows, Mac, Linux, and bare-metal systems, Slint features an easy-to-learn domain-specific language (DSL) that compiles into native code, optimizing for the target device's capabilities. It facilitates collaboration between designers and developers on shared projects and supports business logic development in Rust, C++, JavaScript, or Python.