Themed palette
A 14-hue open-color palette, sizing tokens, and semantic colors. Read every value from the theme — light / dark switching is free.
guise is a batteries-included component layer for gpui — a themed palette, sizing tokens, and over a hundred and thirty composable components, GPU-rendered at native speed. Tailor is the drag-and-drop builder for it, in the same repository: it lays those same components out on a canvas and hands back the Rust.
guise-ui = "1.5"
Drag real components onto a canvas, wire the state and the actions, and export.
Rust you own, with no dependency on Tailor left in it — or write it by hand from the start.
The palette — 14 open-color hues, 10 shades each, read straight from the theme.
A complete component layer, not a widget grab-bag — themed, composable, and native from the first line.
A 14-hue open-color palette, sizing tokens, and semantic colors. Read every value from the theme — light / dark switching is free.
Chainable builders that read the same on every component: .variant(), .color(), .size(), .radius().
Inputs, overlays and data views are gpui entities that own their state and emit events you take with cx.subscribe.
A Flutter-style flexbox layer plus terse row! / col! / zstack! macros for dense layout.
A lightweight React-style layer: Signal, use_state, provide / use_context, and use_form validation.
Embed a real OS web view (WKWebView / WebView2 / WebKitGTK) via wry, positioned inside normal guise layout.
Every Lucide icon as an IconName variant, drawn from an embedded icon font — no asset pipeline, tinted and sized like text.
DevTools shaped like Safari's Web Inspector — an element tree your components record themselves, the box model, resolved styles with the line each came from, plus logs, network and timelines the host feeds.
Check a release feed, install the new version in place — rsync onto the .app, rename over the AppImage — verify its signature, and restart. Prompt included.
Tailor lays these components out on a canvas and writes the Rust — an interface builder that ships in the same repository as the library it draws with.
Transcript, composer, streaming text, reasoning blocks, tool calls, citations and a cost meter — transport-agnostic, so nothing here opens a socket or holds a key.
TableView, DataView, TreeView and VirtualList window their rows — a hundred thousand of them render as cheaply as twenty.
Controlled widgets take a value and a handler. Stateful ones are entities you create with cx.new and subscribe to. Same mental model — native rendering underneath.
Read the component model →cx.subscribe, redraws via cx.notify// a stateful entity: owns its buffer, emits events
let name = cx.new(|cx| {
TextInput::new(cx)
.label("Name")
.placeholder("guise-app")
});
cx.subscribe(&name, |this, _input, e: &TextInputEvent, cx| {
if let TextInputEvent::Change(value) = e {
this.name = value.clone();
cx.notify();
}
})
.detach();
From buttons to a native web view, a code editor and an AI chat kit — a selection of the families below.
One window, seven components, every value read from the theme.
Layout, motion and state — the parts of an app a component grab-bag leaves out.
Tailor is a drag-and-drop builder for guise, shipped in the same repository and downloadable as an app. Its canvas renders the real components against the real theme — there is no second drawing to keep in step — so what you lay out is what it generates, and what it generates is a file you own.
Read about Tailor →//! DashboardScreen — generated by Tailor from Dashboard.
//! …take this file and own it; it has no dependency on Tailor.
use gpui::prelude::*;
use guise::prelude::*;
use super::StatCard;
impl Render for DashboardScreen {
fn render(&mut self, …) -> impl IntoElement {
AppShell::new()
.child(
div()
.flex()
.flex_col()
.gap(px(20.))
.p(px(24.))
.child(
div()
.flex_row()
.gap(px(16.))
.child(StatCard::new())
.child(StatCard::new())
)
)
}
}
Render entity when the screen holds state, a RenderOnce builder when it does notSignal fields; events become cx.listener and cx.subscribeAdd the dependency and open your first window.
guise-ui = "1.5"