Slint for Node.js (Beta)
Slint ↗ is a UI toolkit that supports different programming languages. Slint-node is the integration with Node.js ↗ and Deno ↗.
To get started you use the walk-through tutorial ↗. We also have a Getting Started Template ↗ repository with the code of a minimal application using Slint that can be used as a starting point to your program.
Warning: Beta Slint-node is still in the early stages of development: APIs will change and important features are still being developed.
Slint Language Manual
Section titled “Slint Language Manual”The Slint Language Documentation ↗ covers the Slint UI description language in detail.
API reference
Section titled “API reference”The API group in the sidebar lists types and functions generated from the TypeScript sources in this repository.
Before you run pnpm -C docs/nodejs run dev or pnpm -C docs/nodejs run build, compile the native module and declarations from the repo root:
pnpm -C api/node run buildPrerequisites
Section titled “Prerequisites”To use Slint with Node.js, ensure the following programs are installed:
To use Slint with Deno, ensure the following programs are installed:
Building from Source
Section titled “Building from Source”Slint-node comes with pre-built binaries for macOS, Linux, and Windows. If you’d like to use Slint-node on a system without pre-built binaries, you need to install additional software:
- Rust compiler ↗
- Depending on your operating system, you may need additional components. For a list of required system libraries, see https://github.com/slint-ui/slint/blob/master/docs/building.md#prerequisites ↗.
Getting Started (Node.js)
Section titled “Getting Started (Node.js)”- In a new directory, create a new Node.js project by calling
npm init↗. - Install Slint for your project using
npm install slint-ui↗. - Create a new file called
main.slintwith the following contents:
import { AboutSlint, Button, VerticalBox } from "std-widgets.slint";export component Demo inherits Window { in-out property <string> greeting <=> label.text; VerticalBox { alignment: start; label := Text { text: "Hello World!"; font-size: 24px; horizontal-alignment: center; } AboutSlint { preferred-height: 150px; } HorizontalLayout { alignment: center; Button { text: "OK!"; } } }}This file declares the user interface.
- Create a new file called
index.mjswith the following contents:
import * as slint from "slint-ui";let ui = slint.loadFile(new URL("main.slint", import.meta.url));let demo = new ui.Demo();
await demo.run();This is your main JavaScript entry point:
- Import the Slint API as an ECMAScript module ↗ module. If you prefer you can also import it as CommonJS ↗ module.
- Invoke
loadFile()to compile and load the.slintfile. - Instantiate the
Democomponent declared inmain.slint. - Run it by showing it on the screen and reacting to user input.
- Run the example with
node index.mjs
For a complete example, see /examples/todo/node ↗.
Getting Started (Deno)
Section titled “Getting Started (Deno)”- Create a new file called
main.slintwith the following contents:
import { AboutSlint, Button, VerticalBox } from "std-widgets.slint";export component Demo inherits Window { in-out property <string> greeting <=> label.text; VerticalBox { alignment: start; label := Text { text: "Hello World!"; font-size: 24px; horizontal-alignment: center; } AboutSlint { preferred-height: 150px; } HorizontalLayout { alignment: center; Button { text: "OK!"; } } }}This file declares the user interface.
- Create a new file called
deno.json(a Deno Import Map ↗) with the following contents:
{ "imports": { "slint-ui": "npm:slint-ui" }}- Create a new file called
index.tswith the following contents:
import * as slint from "slint-ui";let ui = slint.loadFile(new URL("main.slint", import.meta.url));let demo = new ui.Demo();
await demo.run();This is your main JavaScript entry point:
- Import the Slint API as an ECMAScript module ↗ module through Deno’s NPM compatibility layer.
- Invoke
loadFile()to compile and load the.slintfile. - Instantiate the
Democomponent declared inmain.slint. - Run it by showing it on the screen and reacting to user input.
- Run the example with
deno run --allow-read --allow-ffi --allow-sys index.ts
Getting Started (bun)
Section titled “Getting Started (bun)”- In a new directory, create a new
bunproject by callingbun init↗. - Install Slint for your project using
bun install slint-ui↗. - Create a new file called
main.slintwith the following contents:
import { AboutSlint, Button, VerticalBox } from "std-widgets.slint";export component Demo inherits Window { in-out property <string> greeting <=> label.text; VerticalBox { alignment: start; label := Text { text: "Hello World!"; font-size: 24px; horizontal-alignment: center; } AboutSlint { preferred-height: 150px; } HorizontalLayout { alignment: center; Button { text: "OK!"; } } }}This file declares the user interface.
- Clear the content of
index.tsand add the following code:
import * as slint from "slint-ui";let ui = slint.loadFile(new URL("main.slint", import.meta.url)) as any;let demo = new ui.Demo();
await demo.run();This is your main TypeScript entry point:
- Import the Slint API as an ECMAScript module ↗ module.
- Invoke
loadFile()to compile and load the.slintfile. - Instantiate the
Democomponent declared inmain.slint. - Run it by showing it on the screen and reacting to user input.
- Run the example with
bun run index.ts
API Overview
Section titled “API Overview”Instantiating a Component
Section titled “Instantiating a Component”Use the loadFile function to load a .slint file. Instantiate the exported component ↗
with the new operator. Access exported callbacks and properties as JavaScript properties on the instantiated component. In addition,
the returned object implements the ComponentHandle interface, to show/hide the instance or access the window.
The following example shows how to instantiate a Slint component from JavaScript.
ui/main.slint
export component MainWindow inherits Window { callback clicked <=> i-touch-area.clicked;
in property <int> counter;
width: 400px; height: 200px;
i-touch-area := TouchArea {}}The exported component is exposed as a type constructor. The type constructor takes as parameter an object which allow to initialize the value of public properties or callbacks.
main.mjs
import * as slint from "slint-ui";// In this example, the main.slint file exports a module which// has a counter property and a clicked callbacklet ui = slint.loadFile(new URL("ui/main.slint", import.meta.url));let component = new ui.MainWindow({ counter: 42, clicked: function() { console.log("hello"); }});Accessing Properties
Section titled “Accessing Properties”Properties ↗ declared as out or in-out in .slint files are visible as JavaScript properties on the component instance.
main.slint
export component MainWindow { in-out property <string> name; in-out property <int> age: 42;}let ui = slint.loadFile(new URL("main.slint", import.meta.url));let instance = new ui.MainWindow();console.log(instance.age); // Prints 42instance.name = "Joe";Setting and Invoking Callbacks
Section titled “Setting and Invoking Callbacks”Callbacks ↗ declared in .slint files are visible as JavaScript function properties on the component instance. Invoke them
as function to invoke the callback, and assign JavaScript functions to set the callback handler.
ui/my-component.slint
export component MyComponent inherits Window { callback clicked <=> i-touch-area.clicked;
width: 400px; height: 200px;
i-touch-area := TouchArea {}}main.mjs
import * as slint from "slint-ui";
let ui = slint.loadFile(new URL("ui/my-component.slint", import.meta.url));let component = new ui.MyComponent();
// connect to a callbackcomponent.clicked = function() { console.log("hello"); };// emit a callbackcomponent.clicked();Type Mappings
Section titled “Type Mappings”The types used for properties in .slint design markup each translate to specific types in JavaScript. The following table summarizes the entire mapping:
.slint Type | JavaScript Type | Notes |
|---|---|---|
int | Number | |
bool | Boolean | |
float | Number | |
string | String | |
color | RgbaColor | |
brush | Brush | |
image | ImageData | |
length | Number | |
physical_length | Number | |
duration | Number | The number of milliseconds |
angle | Number | The angle in degrees |
relative-font-size | Number | Relative font size factor that is multiplied with the Window.default-font-size and can be converted to a length. |
| structure | Object | Structures are mapped to JavaScript objects where each structure field is a property. |
| array | Model |
Arrays and Models
Section titled “Arrays and Models”Array properties ↗ can be set from JavaScript by passing
either Array objects or implementations of the Model interface.
When passing a JavaScript Array object, the contents of the array are copied. Any changes to the JavaScript afterwards will not be visible on the Slint side.
Reading a Slint array property from JavaScript will always return a Model.
component.model = [1, 2, 3];// component.model.push(4); // does not work, because assignment creates a copy.// Use re-assignment instead.component.model = component.model.concat(4);Another option is to set an object that implements the Model interface.
structs
Section titled “structs”An exported struct can be created either by defining an object literal or by using the new keyword.
my-component.slint
export struct Person { name: string, age: int}
export component MyComponent inherits Window { in-out property <Person> person;}main.js
import * as slint from "slint-ui";
let ui = slint.loadFile(new URL("my-component.slint", import.meta.url));let component = new ui.MyComponent();
// object literalcomponent.person = { name: "Peter", age: 22 };
// new keyword (sets property values to default e.g. '' for string)component.person = new ui.Person();
// new keyword with parameterscomponent.person = new ui.Person({ name: "Tim", age: 30 });A value of an exported enum can be set as string or by using the value from the exported enum.
my-component.slint
export enum Position { top, bottom}
export component MyComponent inherits Window { in-out property <Position> position;}main.js
import * as slint from "slint-ui";
let ui = slint.loadFile(new URL("my-component.slint", import.meta.url));let component = new ui.MyComponent();
// set enum value as stringcomponent.position = "top";
// use the value of the enumcomponent.position = ui.Position.bottom;Globals
Section titled “Globals”You can declare globally available singletons ↗ in your
.slint files. If exported, these singletons are accessible as properties on your main
component instance. Each global singleton is represented by an object with properties and callbacks,
similar to API that’s created for your .slint component.
For example the following .slint markup defines a global Logic singleton that’s also exported:
export global Logic { callback to_uppercase(string) -> string;}Assuming this global is used together with the MyComponent from the
previous section, you can access Logic like this:
import * as slint from "slint-ui";
let ui = slint.loadFile(new URL("ui/my-component.slint", import.meta.url));let component = new ui.MyComponent();
component.Logic.to_upper_case = (str) => { return str.toUpperCase();};Note: Global singletons are instantiated once per component. When declaring multiple components for export to JavaScript,
each instance will have their own instance of associated global singletons.
Third-Party Licenses
Section titled “Third-Party Licenses”For a list of the third-party licenses of all dependencies, see the separate Third-Party Licenses page.
© 2026 SixtyFPS GmbH