Get started
Install the crate, write the smallest application that runs, and get the toolchain, the system packages, the feature flags and the examples you need to go further.
cargo new my-app
cd my-app
cargo add teksiloThat is the whole install. Teksilo is at version 0.8.0 and every crate in the workspace shares that number, so there is one version to pin and one set of release notes to read. Pre-1.0 means breaking changes between minor versions: pin the exact version you tested against rather than a caret range, and read the news page before you move.
A minimal app
use teksilo::prelude::*;
use teksilo::widgets::Button;
fn main() {
TeksiloAppBuilder::new()
.theme(intui::light())
.initial_window(
WindowConfig::new()
.title("Hello Teksilo")
.size(400, 300)
.root(|tree, _state| {
tree.add(
Button::new(lit!("Click Me"))
.on_activate_fn(|_ctx| println!("Clicked!")),
)
}),
)
.run();
}Three things in that snippet trip people up:
- The prelude stops short of the widget catalog.
teksilo::prelude::*brings in the core, app, theme, geometry, settings and internationalization types, the native file dialog extension trait, and a few feature-gated surfaces: the toast and notification widgets, plusWebViewandTerminalwhen those features are on. The general catalog is not in it, soButton,TextWidgetandVStackcome from a seconduse teksilo::widgets::{...};. Every example with a user interface carries that line. lit!comes from thei18nfeature. It is on by default. Adefault-features = falsebuild loseslit!,tr!andLocalizedString, and the snippet stops compiling.- Windows are described by a
WindowConfig. There is no.title()or.size()on the application builder itself; a config goes to.initial_window(...), and secondary windows are opened from handler code. Therootclosure receives the widget tree and the window state and returns the id of the root widget, which is why the second parameter is written_statewhen you do not need it.
Reactive state is one type, Signal<T>, and derived values are ordinary maps over it:
use teksilo::prelude::*;
use teksilo::widgets::{Button, TextWidget, VStack};
fn main() {
TeksiloAppBuilder::new()
.theme(intui::light())
.initial_window(
WindowConfig::new()
.title("Counter")
.size(300, 150)
.root(|tree, _state| {
let count = Signal::new(0_i32);
let label = count.map(|n| format!("Count: {n}"));
tree.add(
VStack::new()
.spacing(12.0)
.child(TextWidget::new(lit!("")).text(label))
.child(
Button::new(lit!("Increment"))
.on_activate_fn(move |_| {
count.set(count.get() + 1)
}),
),
)
}),
)
.run();
}Both snippets come from the README, and both compile as written against the 0.8.0 API.
Toolchain and system packages
- Rust. The workspace is edition 2024 with resolver 3, which means a toolchain of 1.85 or newer. No minimum is declared, though: there is no
rust-versionkey and no toolchain file. CI builds and tests onstableacross all three platforms, and a monthly job also runs beta and nightly. Treat current stable as the supported toolchain: nothing older is tested. - Platforms. Linux, Windows and macOS. There are no mobile or web targets.
- Linux packages. For an ordinary application you need what winit, wgpu and arboard link against:
build-essential,pkg-config,libxkbcommon-dev,libwayland-dev,libxcb1-dev,libx11-dev. CI additionally installslibglib2.0-dev,libgtk-3-dev,libwebkit2gtk-4.1-dev,libsoup-3.0-devandlibjavascriptcoregtk-4.1-dev, but only because it builds every example and one of them turns on the optionalweb-viewfeature. GTK and WebKit enter the dependency graph through that feature alone. - Native file dialogs do not pull GTK. They are a default feature, and
rfdis used withdefault-features = falseplus the xdg-portal and Wayland features. - No cmake and no C++ toolchain. The two directories that would need them,
crates/teksilo-analytics-nativeandexamples/telemetry_teksilo, are excluded from the workspace for exactly that reason, so a plaincargo buildandcargo testwork without either.
What you get by default
The default feature set of the teksilo crate is widgets, text, i18n, inspector, toast, file-dialog, clipboard, fonts-arabic and fonts-hebrew. That gives you the widget catalog, the rich-text stack, compile-time-checked translations, the F12 debug inspector (debug builds only), toast notifications, native file dialogs and the system clipboard.
Off by default, added when you need them:
- Theme presets.
theme-material3,theme-fluentandtheme-macos. The Int UI light and dark themes are in the core and need no feature. - Font bundles. The default set bundles Noto Sans for Arabic and Hebrew.
fonts-thai,fonts-devanagari,fonts-cjk-sc,fonts-cjk-jpandfonts-cjk-kradd the other scripts one at a time,fonts-alladds every one, andsystem-emojiloads a color emoji font from the machine at startup. - Async.
asyncfor the opt-in main-thread executor, plustokioorasync-stdfor a reactor when you want to await native runtime futures. web-view. The embedded web view, wry by default. It is a prototype, and the Servo backend (the native Wayland path) is work in progress: it constructs a real engine but is not frame-driven yet.terminal. The terminal widget, over a real PTY.telemetryandautomation. The opt-in analytics stack, and the debug-only bridge that lets an agent drive a running application.
Read the examples
The runnable examples live in the repository, one package each, and most are invoked by a hyphenated package name:
cargo run -p simple-button # the minimal app
cargo run -p widget-catalog # browse most of the catalog
cargo run -p data-collections # lists and trees over the data models
cargo run -p docking # a dockable editor shell
cargo run -p file-dialogs # native open, save and pick-folderwidget-catalog takes a --theme flag to start in a specific preset, one of intui-light, intui-dark, material3-light, material3-dark, fluent-light, fluent-dark, macos-light or macos-dark. simple-button is the closest thing in the repository to the first snippet above, with the inspector and the automation bridge added.
cargo run -p teksilo-widgets-previewer opens a three-pane explorer with live property editing, covering 56 of the widgets.
Before you build something on it
- CJK IME composition is untested by real users. Latin and bidirectional input compose correctly; Chinese, Japanese and Korean input methods need testing by people who use them daily.
- X11 verification breadth is limited. The X11 title bar and drag-and-drop backends ship with protocol tests, but live verification has been against KWin through XWayland, plus Openbox in CI. Other window managers are untested.
Where to go next
- The tour walks through what the framework ships at 0.8.0, including the parts that are prototype or opt-in.
- Documentation points at the guides and the API reference.
- Get involved is for working on the framework itself rather than with it: how to build a checkout, and which checks have to pass.