slint

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 9 Imported by: 0

README

go-slint (wip)

Go bindings for the Slint declarative UI toolkit. Write your UI in .slint, generate a typed Go API from it, and drive it with compile-checked methods.

⚠️ The majority of this repository was generated by an LLM. Review it and use at your own risk it has not yet been used in production.

// app.slint
export component AppWindow inherits Window {
    in-out property <int> counter: 0;
    callback clicked();
}
// main.go  (//go:generate goslint generate -o ui/app.slint.go app.slint)
win, _ := ui.NewAppWindow()
defer win.Close()

win.OnClicked(func() {
    n, _ := win.Counter()
    _ = win.SetCounter(n + 1)
})
win.Run()

Property and callback names are real Go methods. Structs and enums become Go types, arrays become []T, and imported .slint files are embedded — so even a multi-file UI builds into one self-contained binary. A lower-level dynamic API is also available for compiling .slint at runtime. → See the Guide.

Quickstart

You need Go and a C compiler for cgo — gcc/clang on Linux, the Xcode command-line tools on macOS, MinGW-w64 gcc on Windows (not MSVC). You do not need Rust or pkg-config; the native Slint library is downloaded prebuilt. Run goslint doctor to check your toolchain.

go install github.com/rileylov/go-slint/cmd/goslint@latest

goslint init myapp     # scaffold go.mod + app.slint + main.go + ui/
cd myapp
goslint setup          # download the native lib matching your go.mod
goslint dev .          # run; edit app.slint or .go → auto-regenerate & reload

Ship it:

goslint build -o myapp .                # one self-contained desktop binary
goslint android build -o myapp.apk .    # signed APK (arm64-v8a + x86_64)

goslint is the whole interface: init, setup, generate, dev, build, run, android, doctor, uninstall. Full walkthrough in the Guide.

Platforms

Platform Status
Linux (amd64) ✅ tested
Android (arm64-v8a) ✅ tested
Windows (amd64) ✅ tested
macOS, iOS ❌ (no hardware to test on)

Desktop targets link libgoslint (and the Slint interpreter) statically, leaving only ubiquitous system libraries — on Linux, OpenGL and fontconfig (the fontconfig dev package is also needed at build time).

Documentation

  • Guide (DOCS.md) — step-by-step: properties, callbacks, globals, structs, enums, arrays, models, the dynamic API, and shipping.
  • Architecture (CLAUDE.md) — the three layers, building the shim from source, and tracking upstream Slint (make update-slint).
  • Examples — runnable typed and dynamic apps.

License

The go-slint binding code here is MIT.

go-slint links the Slint toolkit, which is separately licensed and not covered by this repository's MIT license. Slint is tri-licensed:

  • GPLv3 — free, your app must be GPL-compatible;
  • a royalty-free license for desktop/mobile/web apps — free, with a "Made with Slint" attribution; this covers all of go-slint's supported targets;
  • a commercial license — paid; removes attribution.

Any app you build with go-slint, and the prebuilt libgoslint binaries in Releases (which embed Slint), are governed by Slint's license — choose and comply with one of the options above. See LICENSES for details.

Documentation

Overview

Package slint provides Go bindings for the Slint declarative UI toolkit.

UIs are written in Slint's .slint markup language and driven from Go. This package compiles .slint markup at runtime (via Slint's interpreter), creates component instances, and lets you read and write properties, handle callbacks, back models, load images, and run timers — all from Go.

Threading

Slint is thread-affine. Compile, Create, property/callback access, and Run must all happen on a single OS thread. Lock it at program start:

func init() { runtime.LockOSThread() }

To touch the UI from another goroutine, post work with InvokeFromEventLoop.

A minimal program

package main

import (
	_ "embed"
	"runtime"

	"github.com/rileylov/go-slint"
)

func init() { runtime.LockOSThread() }

//go:embed app.slint
var ui string

func main() {
	app, err := slint.Compile(ui, slint.WithStyle("fluent"))
	if err != nil {
		panic(err)
	}
	defer app.Close()

	win, err := app.Create("AppWindow")
	if err != nil {
		panic(err)
	}
	defer win.Close()

	win.OnCallback("clicked", func([]any) any {
		n, _ := win.Int("counter")
		win.Set("counter", n+1)
		return nil
	})
	win.Run()
}

Value mapping

Properties and callback arguments/returns convert between Slint and Go as:

void                          <-> nil
int / float / length / angle  <-> float64
bool                          <-> bool
string                        <-> string
struct / anonymous object     <-> map[string]any
enum                          <-> [Enum]{Type, Value}
color / solid brush           <-> [Color]
gradient brush                <-> [Gradient] (linear or radial)
image                         <-> *[Image] (write; load via [LoadImage])
array / model                 <-> []any (read) or [*ModelHandle] (write)

Build a writable model with NewSliceModel (or NewModel for a custom Model) and assign it to an array/model property; mutating it notifies Slint.

See the cmd/examples directory for runnable apps (hello, counter, todo, clock, interop, chartstress) and CLAUDE.md for the architecture.

The package overview lives in doc.go.

Index

Constants

View Source
const (
	TimerSingleShot = slintsys.TimerSingleShot
	TimerRepeated   = slintsys.TimerRepeated
)

Timer modes.

Variables

This section is empty.

Functions

func ClearTranslator added in v0.4.0

func ClearTranslator()

ClearTranslator removes the translator so `@tr` shows its source strings again.

func ClipboardText added in v0.4.0

func ClipboardText() string

ClipboardText returns the system clipboard's text ("" if empty or unavailable). The clipboard is provided by the backend, so call it once a window exists.

func InitHeadless

func InitHeadless() error

InitHeadless installs the headless testing backend (mock time, no real windows). Intended for tests; call once per process on the UI thread.

func InvokeFromEventLoop

func InvokeFromEventLoop(fn func()) error

InvokeFromEventLoop posts fn to run once on the event-loop (UI) thread. Safe to call from any goroutine; it is the only safe way to touch UI state (properties, models, callbacks) from a background goroutine.

func LiveReload

func LiveReload(path, component string, bind func(*Instance) error, opts ...Option) error

LiveReload compiles the .slint file at path, creates component (or the last exported one if component is ""), wires it with bind, shows it, and then hot-reloads whenever any .slint file beside it changes on disk — recompiling and swapping the window in place, with no Go rebuild. It runs the event loop and returns when the window is closed.

It's the engine behind `goslint dev`: because the interpreter loads markup at runtime, editing a .slint and saving updates the UI live. bind is re-invoked on each reload with the fresh instance, so wire your callbacks/properties there (note: property state resets on reload). Call runtime.LockOSThread first, as with any Slint program.

func MockElapsedTime

func MockElapsedTime(ms uint64)

MockElapsedTime advances the headless backend's mock clock by ms milliseconds.

func Quit

func Quit() error

Quit asks the running event loop to exit.

func Run

func Run() error

Run enters the Slint event loop until the last window closes or Quit is called. It blocks and must run on the UI thread.

func RunUntilQuit added in v0.4.0

func RunUntilQuit() error

RunUntilQuit is like Run but does not exit when the last window closes — it runs until Quit. Use it for multi-window apps that open and close windows dynamically. Show at least one window before calling it.

func SetClipboardText added in v0.4.0

func SetClipboardText(s string) error

SetClipboardText sets the system clipboard text.

func SetTranslator added in v0.4.0

func SetTranslator(fn func(msgid string) string) error

SetTranslator installs a function that translates `@tr("…")` source strings at runtime, and re-renders existing translations. Call it again to switch languages (e.g. with a different lookup table); the handler returns the original string when it has no translation. Call on the UI thread, after a window/backend exists.

func SingleShot

func SingleShot(intervalMs uint64, fn func())

SingleShot fires fn once after the given number of milliseconds.

func Version

func Version() string

Version returns the Slint version these bindings were built against.

Types

type Callback

type Callback = slintsys.CallbackFunc

Callback is a Go handler invoked by Slint. Its args and return use the same Go value representation as properties (float64, bool, string, map[string]any, Enum, nil, ...).

type Color

type Color = slintsys.Color

Color is an RGBA color (a `color` property, or a solid `brush`).

type Compilation

type Compilation struct {
	// contains filtered or unexported fields
}

Compilation is a successfully compiled set of components.

func Compile

func Compile(source string, opts ...Option) (*Compilation, error)

Compile compiles `.slint` source. It returns a *DiagnosticError if the source has errors.

func CompileFile

func CompileFile(path string, opts ...Option) (*Compilation, error)

CompileFile compiles a `.slint` file from disk.

func CompileSource added in v0.3.0

func CompileSource(path, source string, opts ...Option) (*Compilation, error)

CompileSource compiles markup from a string while treating it as if it lived at `path`, so relative imports (and @image-url) resolve from path's directory on disk. Generated typed code uses this so multi-file components work; for a single embedded file with no relative imports, plain Compile is enough.

func (*Compilation) Close

func (c *Compilation) Close()

Close releases the compilation's resources.

func (*Compilation) ComponentNames

func (c *Compilation) ComponentNames() []string

ComponentNames lists the exported components.

func (*Compilation) Create

func (c *Compilation) Create(name string) (*Instance, error)

Create instantiates the named component.

type DiagnosticError

type DiagnosticError struct {
	Diagnostics []slintsys.Diagnostic
}

DiagnosticError reports one or more compiler errors.

func (*DiagnosticError) Error

func (e *DiagnosticError) Error() string

type Enum

type Enum = slintsys.Enum

Enum is the Go representation of a Slint enumeration value (e.g. Enum{Type: "TextHorizontalAlignment", Value: "center"}). Structs are represented as map[string]any.

type FileLoader added in v0.3.0

type FileLoader = slintsys.FileLoader

FileLoader resolves a `.slint` import path to source; ok=false means "not found" (normal include-path/disk resolution then proceeds). Builtins like std-widgets are handled internally and never passed to it.

type Gradient added in v0.2.0

type Gradient = slintsys.Gradient

Gradient is a gradient `brush` value (linear by default, or Radial); set it on a brush/color property, or read one back from Get. GradientStop is one stop.

type GradientStop added in v0.2.0

type GradientStop = slintsys.GradientStop

GradientStop is one stop of a Gradient: Pos in 0..=1 with a Color.

type Image

type Image = slintsys.Image

Image is a loaded image; assign it to an `image` property and Free it when done.

func LoadImage

func LoadImage(path string) (*Image, error)

LoadImage loads an image (PNG/JPEG) from a file path.

func NewImage added in v0.4.0

func NewImage(src image.Image) (*Image, error)

NewImage builds an image from any Go image.Image — decoded (image/png, image/jpeg), drawn (image/draw, plotting libs), or generated. Use this to display dynamic content the way Slint's SharedPixelBuffer does in Rust. The pixels are copied, so the source can be reused or freed afterward.

It converts to non-premultiplied RGBA (Slint's expected format); note Go's image.RGBA is *premultiplied*, which this handles correctly.

func NewImageRGB added in v0.4.0

func NewImageRGB(pix []byte, w, h int) (*Image, error)

NewImageRGB builds an image from a tightly-packed RGB8 buffer (w*h*3 bytes).

func NewImageRGBA added in v0.4.0

func NewImageRGBA(pix []byte, w, h int) (*Image, error)

NewImageRGBA builds an image from a tightly-packed RGBA8 buffer (w*h*4 bytes, row-major, non-premultiplied alpha). The bytes are copied.

type Instance

type Instance struct {
	// contains filtered or unexported fields
}

Instance is a live component instance.

func (*Instance) Bool

func (i *Instance) Bool(name string) (bool, error)

Bool reads a boolean property.

func (*Instance) Close

func (i *Instance) Close()

Close releases the instance.

func (*Instance) Float

func (i *Instance) Float(name string) (float64, error)

Float reads a numeric property.

func (*Instance) Get

func (i *Instance) Get(name string) (any, error)

Get reads a property as a Go value (float64, bool, string, or nil).

func (*Instance) GetGlobal

func (i *Instance) GetGlobal(global, name string) (any, error)

GetGlobal reads a property of an exported global singleton.

func (*Instance) Hide

func (i *Instance) Hide() error

func (*Instance) Int

func (i *Instance) Int(name string) (int, error)

Int reads a numeric property as an int.

func (*Instance) Invoke

func (i *Instance) Invoke(name string, args ...any) (any, error)

Invoke calls a callback or function, returning its result (nil for void).

func (*Instance) InvokeGlobal

func (i *Instance) InvokeGlobal(global, name string, args ...any) (any, error)

InvokeGlobal calls a callback or function on an exported global.

func (*Instance) OnCallback

func (i *Instance) OnCallback(name string, fn Callback) error

OnCallback installs a handler for the named callback.

func (*Instance) OnCloseRequested added in v0.4.0

func (i *Instance) OnCloseRequested(handler func() (allowClose bool))

OnCloseRequested registers a handler invoked when the window's close is requested (the user clicking the close button, or RequestClose). Return true to allow the window to close, false to keep it open — e.g. to show a confirm dialog or save first. Runs on the event loop.

func (*Instance) OnGlobalCallback

func (i *Instance) OnGlobalCallback(global, name string, fn Callback) error

OnGlobalCallback installs a handler for a callback on an exported global.

func (*Instance) RegisterFontFromMemory added in v0.4.0

func (i *Instance) RegisterFontFromMemory(data []byte) error

RegisterFontFromMemory registers a font from bytes (e.g. a go:embed'd .ttf). The data is copied and kept for the process. (You can also just `import "font.ttf"` in your .slint, which the interpreter registers for you.)

func (*Instance) RegisterFontFromPath added in v0.4.0

func (i *Instance) RegisterFontFromPath(path string) error

RegisterFontFromPath registers a TrueType/OpenType font file so `.slint` `font-family` can use it. It applies to all windows (registered into the shared context); call it before the text using the font is shown.

func (*Instance) RequestClose added in v0.4.0

func (i *Instance) RequestClose()

RequestClose asks the window to close, running the OnCloseRequested handler — as if the user clicked the close button.

func (*Instance) RequestRedraw added in v0.2.0

func (i *Instance) RequestRedraw()

func (*Instance) Run

func (i *Instance) Run() error

func (*Instance) ScaleFactor added in v0.2.0

func (i *Instance) ScaleFactor() float32

func (*Instance) Set

func (i *Instance) Set(name string, v any) error

Set writes a property from a Go value.

func (*Instance) SetFullscreen added in v0.2.0

func (i *Instance) SetFullscreen(on bool)

func (*Instance) SetGlobal

func (i *Instance) SetGlobal(global, name string, v any) error

SetGlobal writes a property of an exported global singleton.

func (*Instance) SetMaximized added in v0.2.0

func (i *Instance) SetMaximized(on bool)

func (*Instance) SetMinimized added in v0.2.0

func (i *Instance) SetMinimized(on bool)

func (*Instance) SetWindowPosition added in v0.2.0

func (i *Instance) SetWindowPosition(x, y int)

func (*Instance) SetWindowSize added in v0.2.0

func (i *Instance) SetWindowSize(w, h int)

func (*Instance) Show

func (i *Instance) Show() error

Show makes the window visible. Hide hides it. Run shows then runs the loop.

func (*Instance) Snapshot added in v0.4.0

func (i *Instance) Snapshot() (*image.NRGBA, error)

Snapshot renders the window's current contents to an image.NRGBA — handy for screenshots, export (encode it with image/png), or visual tests. It may re-render and can be slow; the window should be created (and usually shown) first.

func (*Instance) SnapshotRGBA added in v0.4.0

func (i *Instance) SnapshotRGBA() (pix []byte, w, h int, err error)

SnapshotRGBA is like Snapshot but returns the raw straight-RGBA8 bytes (w*h*4) without allocating an image, for callers that handle pixels directly.

func (*Instance) Str

func (i *Instance) Str(name string) (string, error)

Str reads a string property.

func (*Instance) WindowPosition added in v0.2.0

func (i *Instance) WindowPosition() (x, y int)

func (*Instance) WindowSize added in v0.2.0

func (i *Instance) WindowSize() (w, h int)

Window control. Sizes and positions are in physical pixels; divide by ScaleFactor to get logical (.slint) pixels. These act on the instance's window and are most reliable once it's shown.

Note: on Wayland the compositor controls window placement, so SetWindowPosition/WindowPosition are no-ops there (they work on X11, Windows, and macOS). Run on X11 — e.g. with WAYLAND_DISPLAY unset — to use positioning.

type Model

type Model = slintsys.Model

Model is a data source backing a Slint model property / `for` loop.

type ModelHandle

type ModelHandle = slintsys.ModelHandle

ModelHandle binds a Model for use as a property value; report data changes via its Notify* methods. Obtain one with NewModel or SliceModel.Handle.

func NewModel

func NewModel(m Model) *ModelHandle

NewModel binds a custom Model implementation so it can be assigned to a property.

type Option

type Option func(*slintsys.Compiler)

Option configures a compilation.

func WithFileLoader added in v0.3.0

func WithFileLoader(fn FileLoader) Option

WithFileLoader installs a fallback resolver for `.slint` imports, letting a multi-file component compile entirely from in-memory source (no files on disk). Generated typed code uses this to embed every imported file.

func WithIncludePaths

func WithIncludePaths(paths ...string) Option

WithIncludePaths sets the paths used to resolve `.slint` imports.

func WithLibraryPaths added in v0.2.0

func WithLibraryPaths(libs map[string]string) Option

WithLibraryPaths maps `@library` import names to their paths, e.g. WithLibraryPaths(map[string]string{"mylib": "./libs/mylib"}) resolves `import { Foo } from "@mylib/foo.slint"`.

func WithStyle

func WithStyle(style string) Option

WithStyle selects the widget style (e.g. "fluent", "material", "cupertino"). Required for `.slint` files that import "std-widgets.slint".

type SliceModel

type SliceModel struct {
	// contains filtered or unexported fields
}

SliceModel is a built-in slice-backed Model whose mutators auto-notify Slint.

func NewSliceModel

func NewSliceModel(items ...any) *SliceModel

NewSliceModel creates a slice-backed model from the given items.

func (*SliceModel) Append

func (s *SliceModel) Append(v any)

Append adds an item and notifies Slint.

func (*SliceModel) Close

func (s *SliceModel) Close()

Close releases the model's binding handle.

func (*SliceModel) Handle

func (s *SliceModel) Handle() *ModelHandle

Handle returns the binding handle (also accepted directly by property setters).

func (*SliceModel) Len

func (s *SliceModel) Len() int

Len reports the number of rows.

func (*SliceModel) RemoveAt

func (s *SliceModel) RemoveAt(row int)

RemoveAt removes the item at row and notifies Slint.

func (*SliceModel) RowCount

func (s *SliceModel) RowCount() int

func (*SliceModel) RowData

func (s *SliceModel) RowData(row int) any

func (*SliceModel) SetRowData

func (s *SliceModel) SetRowData(row int, v any)

type Timer

type Timer = slintsys.Timer

Timer fires a Go callback after an interval. Timers fire only while the event loop runs (Run); create and start them after Create.

func NewTimer

func NewTimer() *Timer

NewTimer creates a stopped timer.

Directories

Path Synopsis
cmd
examples/chartstress command
Shared throughput-harness logic for desktop (main.go) and Android (app_android.go).
Shared throughput-harness logic for desktop (main.go) and Android (app_android.go).
examples/clock command
Command clock is an interactive go-slint example using the TYPED API: a repeating Timer driven from Go updates the typed `ticks` property once a second.
Command clock is an interactive go-slint example using the TYPED API: a repeating Timer driven from Go updates the typed `ticks` property once a second.
examples/counter command
Command counter is an interactive go-slint example using the TYPED API (generated by `goslint generate` — see the directive).
Command counter is an interactive go-slint example using the TYPED API (generated by `goslint generate` — see the directive).
examples/gradient command
Command gradient demonstrates building gradient brushes in Go (slint.Gradient) and assigning them to a `brush` property: linear at various angles, radial, a multi-stop rainbow, and an animated rotating gradient driven by a timer.
Command gradient demonstrates building gradient brushes in Go (slint.Gradient) and assigning them to a `brush` property: linear at various angles, radial, a multi-stop rainbow, and an animated rotating gradient driven by a timer.
examples/hello command
Command hello shows a minimal Slint window from Go.
Command hello shows a minimal Slint window from Go.
examples/image command
Command image generates an image in Go and displays it in the UI via slint.NewImage (the SharedPixelBuffer path) — no image file on disk.
Command image generates an image in Go and displays it in the UI via slint.NewImage (the SharedPixelBuffer path) — no image file on disk.
examples/interop command
Shared Go ⇄ Slint interop logic, used by both the desktop entry (main.go) and the Android entry (app_android.go).
Shared Go ⇄ Slint interop logic, used by both the desktop entry (main.go) and the Android entry (app_android.go).
examples/multifile command
Command multifile is a TYPED example whose .slint imports another .slint (components/card.slint).
Command multifile is a TYPED example whose .slint imports another .slint (components/card.slint).
examples/multiwindow command
Command multiwindow shows several top-level windows from one app.
Command multiwindow shows several top-level windows from one app.
examples/todo command
Command todo is an interactive go-slint example showing a live model: a Go SliceModel backs the list, and add/delete are handled in Go.
Command todo is an interactive go-slint example showing a live model: a Go SliceModel backs the list, and add/delete are handled in Go.
examples/typed command
Command typed is the hello example using the TYPED API generated by `goslint generate` (see the //go:generate directive).
Command typed is the hello example using the TYPED API generated by `goslint generate` (see the //go:generate directive).
examples/window command
Command window demonstrates Go-side window control: resizing, positioning, maximize/fullscreen, reading back size/position/scale-factor, and close handling (OnCloseRequested / RequestClose — confirm before exit).
Command window demonstrates Go-side window control: resizing, positioning, maximize/fullscreen, reading back size/position/scale-factor, and close handling (OnCloseRequested / RequestClose — confirm before exit).
goslint command
Command goslint provisions the native Slint shim library for the go-slint bindings and wraps `go build`/`go run` with the right linker configuration.
Command goslint provisions the native Slint shim library for the go-slint bindings and wraps `go build`/`go run` with the right linker configuration.
goslint-gen command
Command goslint-gen generates a typed Go API from a .slint file.
Command goslint-gen generates a typed Go API from a .slint file.
Package slintsys is the low-level cgo binding to the goslint-sys C ABI (Layer 1).
Package slintsys is the low-level cgo binding to the goslint-sys C ABI (Layer 1).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL