# Gesso > A declarative UI toolkit for the web in the spirit of SwiftUI and Jetpack Compose: components that run once, a real layout engine with typed props, and a theme instead of CSS. The interface is drawn to a canvas from a worker. Gesso is not React and has no DOM. A component function runs once, state is a cell bound into the tree, layout is `row`, `column` and `box` with typed props, and colour comes from theme tokens. Read "Components run once" and "Cells and bindings" before writing a component. Every page below is also available as markdown at its URL with `.md` appended, and the whole site is one file at https://gesso-docs.vercel.app/llms-full.txt. ## Guide - [Why Gesso](https://gesso-docs.vercel.app/guide/why-gesso.md): The case for Gesso, in full. What it does differently, what has been measured, how it compares to the alternatives, and where it does not belong. - [What Gesso is](https://gesso-docs.vercel.app/guide/what-is-gesso.md): What Gesso is, a declarative UI toolkit for web applications, the three things that follow from drawing to a canvas in a worker, and when to use something else. - [Is Gesso for your project?](https://gesso-docs.vercel.app/guide/is-gesso-for-you.md): A one-minute decision: the applications Gesso is for, the pages it is not for, and what to use instead of it in each case. - [Built for AI agents](https://gesso-docs.vercel.app/guide/built-for-agents.md): How Gesso is built for AI agents: every app is an MCP server whose tools are the channel contracts you already wrote, and every app is easy for a coding agent to write. - [Installation](https://gesso-docs.vercel.app/guide/installation.md): Set up a project against the Gesso packages, and choose between the worker and single-thread configurations. - [Your first component](https://gesso-docs.vercel.app/guide/counter.md): Write a component, bind a value into a node, and handle a click, with the counter that runs on this page. - [Components run once](https://gesso-docs.vercel.app/guide/components-run-once.md): Why a Gesso component function runs exactly once, and what that changes about where state and derived values go. - [Cells and bindings](https://gesso-docs.vercel.app/guide/cells-and-bindings.md): Choosing between a prop, an internal state cell and a computed one, and what each one costs per frame. - [Lists and conditionals](https://gesso-docs.vercel.app/guide/lists-and-conditionals.md): Drawing a list that changes, and a child that comes and goes, with each and show. - [Inputs and outputs](https://gesso-docs.vercel.app/guide/inputs-and-outputs.md): What a component takes and what it sends, how a parent passes each, and why both are cells. - [Layout basics](https://gesso-docs.vercel.app/guide/layout-basics.md): Rows, columns and boxes; the two alignment props; typed lengths; and the sizing rules that decide who grows. - [Text](https://gesso-docs.vercel.app/guide/text.md): Wrapping, clamping and ellipsis; how a paragraph sizes its box; and why baseline alignment exists. - [Rich text](https://gesso-docs.vercel.app/guide/rich-text.md): Runs of style inside one paragraph: bold, italic, code, colour, underline and inline links, all in a single text element. - [Using components](https://gesso-docs.vercel.app/guide/using-components.md): Building a form from gesso-components, what each control brings with it, and what stays your job. - [Forms](https://gesso-docs.vercel.app/guide/forms.md): Forms in Gesso, the form group, validators that compose, field arrays, and what happens while a check is still being answered. - [Light and dark](https://gesso-docs.vercel.app/guide/appearance.md): Why a canvas inherits no appearance from the page, how the shell reports light or dark, and how a component follows it. - [State and services](https://gesso-docs.vercel.app/guide/state-and-services.md): Where application state lives when a component runs once: a service while it stays on the render thread, a channel once it crosses one. - [Workers](https://gesso-docs.vercel.app/guide/workers.md): What runs in the render worker, what the main thread still owns, and how to move an application across that line. - [Testing](https://gesso-docs.vercel.app/guide/testing.md): Mount a component with no browser, query it the way an assistive technology does, and read back why a box came out the size it did. ## Layout - [Flex in full](https://gesso-docs.vercel.app/layout/flex.md): Direction, the two axes, grow and shrink and basis, wrapping, and the places the model parts company with CSS. - [Grid](https://gesso-docs.vercel.app/layout/grid.md): Tracks, spans and gaps, what each track size means, and the point at which nesting rows inside columns stops being the right answer. - [Custom layouts](https://gesso-docs.vercel.app/layout/custom-layouts.md): A node whose children an application measures and places itself, in the engine's own constraints vocabulary, with an explain of its own. - [Layouts that change](https://gesso-docs.vercel.app/layout/responsive.md): Container queries: a box that branches on the room it has rather than on the size of the window, and what a band costs. - [Insets](https://gesso-docs.vercel.app/layout/insets.md): A floating bar publishes the room it occupies and a screen keeps clear of it, along with the safe area and the soft keyboard. - [Right to left](https://gesso-docs.vercel.app/layout/right-to-left.md): Logical padding and margin, and what mirrors when a subtree reads right to left. - [Overflow and scrolling](https://gesso-docs.vercel.app/layout/overflow-and-scrolling.md): What clips, what scrolls, where a scroll offset lives, and what the main thread is left doing while a list scrolls in the render worker. - [Sticky positioning](https://gesso-docs.vercel.app/layout/sticky.md): A header that holds at the edge of its scroll container until its own group scrolls away, and what that costs in layout. - [Positioning and overlays](https://gesso-docs.vercel.app/layout/positioning-and-overlays.md): Taking a box out of flow, the containing block it is placed against, anchored placement that flips and shifts at the viewport edge, and the layer overlays live in. - [Virtualization](https://gesso-docs.vercel.app/layout/virtualization.md): A list of any length that mounts only the rows in view, what the estimate and the corrections do, and what the window costs per frame. - [Asking the engine why](https://gesso-docs.vercel.app/layout/explain.md): engine.explain: the rule that fixed each axis, in sentences, next to a failing assertion and under the pointer. ## Interaction - [Pointer and keyboard](https://gesso-docs.vercel.app/interaction/pointer-and-keyboard.md): What a pointer event carries, how hit testing chooses who gets it, how a key reaches a component, what is focusable and in what order, and what the shell still does for input. - [Touch and gestures](https://gesso-docs.vercel.app/interaction/touch-and-gestures.md): How a finger differs from a cursor, which gesture a press resolves to, why a drag is a long press first, and what makes a scroll container answer to a pan. - [Drag and drop](https://gesso-docs.vercel.app/interaction/drag-and-drop.md): Somewhere to put a drag down: typed payloads, drop zones that show their state, a list that reorders as the carried row crosses it, auto-scroll, and the shape a file dragged in from the desktop arrives in. - [Shortcuts](https://gesso-docs.vercel.app/interaction/shortcuts.md): A scoped, prioritised shortcut registry with chords, that a component or a route registers into and a palette can list. - [Focus and traps](https://gesso-docs.vercel.app/interaction/focus-and-traps.md): Focus as something a component can reach, autofocus, moving the caret to the field that failed, confining the keyboard to a dialog, and drawing a ring around whatever holds it. - [Text editing and IME](https://gesso-docs.vercel.app/interaction/text-editing-and-ime.md): The editable node under the component library, its caret and selection, the commands it answers to, composition from an IME, and what the platform still owns. - [Selection](https://gesso-docs.vercel.app/interaction/selection.md): Highlighting and copying text that nobody types into: which text is selectable, how a selection spans nodes, what copy sends to the shell, and what the model does not do. - [Find](https://gesso-docs.vercel.app/interaction/find.md): Find in an application's own text: the bar, the session a component drives, what is searched and what is not, and how text opts in or out. - [Modifiers](https://gesso-docs.vercel.app/interaction/modifiers.md): Attaching behaviour to an element without wrapping it: the modifiers prop, the override cascade, how a modifier survives the rebuild of the element it is on, and what one is allowed to touch. - [Writing a modifier](https://gesso-docs.vercel.app/interaction/writing-a-modifier.md): Writing a modifier of your own against gesso-core alone: defineModifier and typed arguments, the host API, the three ordering rules, configuration through the theme rather than a new property, and a worked example that runs in the playground. ## Appearance - [Themes and the environment](https://gesso-docs.vercel.app/appearance/themes-and-the-environment.md): A theme is one value in the environment: what it holds, what a colour token resolves against, and how an application provides a palette of its own. - [The type scale](https://gesso-docs.vercel.app/appearance/typography.md): The type scale: what a text style holds, how one provided in the environment reaches text that names nothing, and how an application replaces it. - [Fonts](https://gesso-docs.vercel.app/appearance/fonts.md): Web fonts on a canvas: declaring a family and its fallback stack, loading it into the render worker, and what happens to text while the file is on its way. - [Motion](https://gesso-docs.vercel.app/appearance/motion.md): Tweens, springs and the ticks phase: how a property travels between two values, how a reorder animates itself, and what reduced motion turns all of it into. - [Enter and exit](https://gesso-docs.vercel.app/appearance/enter-and-exit.md): Presence and motion(): where an element comes in from, what keeps it on screen while it leaves, and the six channels that cost no layout. - [Shared elements](https://gesso-docs.vercel.app/appearance/shared-elements.md): sharedElement(): how one screen's element continues as another screen's, why it is FLIP over the live graph rather than a snapshot, and where it stops. ## Media - [Images and the resolver](https://gesso-docs.vercel.app/media/images-and-the-resolver.md): How a picture reaches the canvas: the resolver that fetches and decodes it, where that work happens, and how objectFit puts it in a box. - [Icons](https://gesso-docs.vercel.app/media/icons.md): Icons are paths, not files: how one is rasterised, what that costs, and why an icon is the one thing here that cannot resolve a palette colour at paint. - [Video](https://gesso-docs.vercel.app/media/video.md): Video on a canvas: a decoder in the render worker, a surface with a version, frames driven by the animation driver, and what only a browser can verify. ## Structure - [Routing](https://gesso-docs.vercel.app/structure/routing.md): Declaring routes with full paths and typed params, navigating, and what a route change does to the tree. - [Channels and the barrier](https://gesso-docs.vercel.app/structure/channels-and-the-barrier.md): The declared contract between an application and its view: one token, typed commands out, patches in, and a single structural differ. - [Channels from another process](https://gesso-docs.vercel.app/structure/channels-from-another-process.md): Serving channels from outside the page: a server on the person's machine, a desktop main process, or anything that can carry a string, with gesso-framework/remote. - [Shell services](https://gesso-docs.vercel.app/structure/shell-services.md): ShellService: the clipboard, URLs, files and the appearance signal a component in a render worker reaches through the thread that has a window. - [Undo and redo](https://gesso-docs.vercel.app/structure/undo.md): An application-level undo stack: named transactions, coalescing, redo, and the one keyboard path that shares Mod+Z with a text field. - [Remembering state](https://gesso-docs.vercel.app/structure/persistence.md): Where an application keeps state that survives being closed: three storage adapters, hydration on start, and what happens when a store is denied or full. - [Errors and the overlay](https://gesso-docs.vercel.app/structure/errors-and-the-overlay.md): Where an exception in application code is caught, what it costs the running app, and how a failure inside a render worker reaches the page at all. - [Desktop windows](https://gesso-docs.vercel.app/structure/desktop-windows.md): Running a Gesso application in an Electrobun window: the state in the main process, a webview per window, and what the transport between them costs. - [Gesso on Electrobun](https://gesso-docs.vercel.app/structure/gesso-on-electrobun.md): Gesso on Electrobun from scaffold to native window: the process model, the adapter, the Hutch toolchain, developing and building, and exactly which webview engines have been run. - [Agents and MCP](https://gesso-docs.vercel.app/structure/agents-and-mcp.md): Hand an application to an AI agent: its channels as MCP tools and resources, with the commands a person must approve asked about first. ## Access - [Semantics](https://gesso-docs.vercel.app/access/semantics.md): What a component tells an assistive technology: role, label, value and states, where the accessible name comes from, and what the diff costs per frame. - [The mirror](https://gesso-docs.vercel.app/access/the-mirror.md): The off-screen DOM the shell keeps over the canvas, how a record becomes an element, and how a screen reader's press comes back as ordinary input. - [Keyboard operability](https://gesso-docs.vercel.app/access/keyboard.md): Keyboard operability as a contract every component honours, from one tab stop per widget to Escape closing the overlay on top. ## Rendering - [Canvas2D and WebGPU](https://gesso-docs.vercel.app/rendering/canvas2d-and-webgpu.md): The two rendering backends: how an application picks one, what they share, where they differ, and what parity is checked against. ## Tooling - [Devtools](https://gesso-docs.vercel.app/tooling/devtools.md): What gesso-devtools gives you, how each tool is mounted, and why they are DOM over the canvas rather than drawn inside it. - [Inspecting a node](https://gesso-docs.vercel.app/tooling/inspecting-a-node.md): Read what a node is, who decided each of its values, what it inherits, and which component rendered it. - [Frames and phases](https://gesso-docs.vercel.app/tooling/frames-and-phases.md): The seven phases of a Gesso frame, and reading the profiler strip that shows where they went. - [The action log](https://gesso-docs.vercel.app/tooling/the-action-log.md): Record every command and patch crossing a channel, and put the view back to what it showed at any step. - [The devtools panel](https://gesso-docs.vercel.app/tooling/the-devtools-panel.md): The Gesso panel in Chrome devtools, and the same panel as a pane in your page. The node tree, a node's report, the workers' consoles, the frame profiler and the action log in one place. - [The Vite plugin](https://gesso-docs.vercel.app/tooling/vite-plugin.md): One plugin that writes the worker construction, the hot-replacement wiring and the error overlay, and says when a save is about to reload the page. - [Hot module replacement](https://gesso-docs.vercel.app/tooling/hot-module-replacement.md): Rebuild the tree from new code while services and channel data carry on, in two lines and with one thing you have to hand over. - [Reporting errors](https://gesso-docs.vercel.app/tooling/reporting-errors.md): What a shipped Gesso application does with a failure the overlay would have drawn, and the shape of the reporter that receives it. - [create-gesso-app](https://gesso-docs.vercel.app/tooling/create-gesso-app.md): Scaffold a Vite project whose interface is built, laid out, painted and hit-tested in a render worker. ## Reference - [Properties](https://gesso-docs.vercel.app/reference/properties.md): Every property in the core registry: what it defaults to, whether it inherits, and what changing it invalidates. - [API index](https://gesso-docs.vercel.app/reference/api.md): The names an application imports from Gesso, grouped by what they are for and linked to the page that teaches each one. - [The render-worker protocol](https://gesso-docs.vercel.app/reference/render-worker-protocol.md): The render-worker protocol: every message the shell and the render worker exchange, what each one carries, and why an application never sends one. ## Components - [Overview](https://gesso-docs.vercel.app/components/index.md): What gesso-components is, the contract every control in it honours, and how to read the pages that follow. - [Restyling the controls](https://gesso-docs.vercel.app/components/restyling.md): Restyling the library: the control token group on the theme, what it holds, how a provider changes it, and why no component takes a colour prop. - [Button](https://gesso-docs.vercel.app/components/button.md): Button: the themed wrapper over the button element, with variant, tone and size, one label that is both the words and the name, and the interaction and focus ring already on it. - [Link](https://gesso-docs.vercel.app/components/link.md): Link: a control that goes somewhere, with the role that says so, the shell request that stands in for an anchor, in-app destinations that open somewhere new on Cmd-click, its underline modes and its keyboard. - [Chip](https://gesso-docs.vercel.app/components/chip.md): Chip: a pill that is on or off, for a row of filters, with its variants, props, keyboard map and semantics. - [Badge](https://gesso-docs.vercel.app/components/badge.md): Badge: a count or a short status marker attached to something else, with its tones, props and the semantics it declines to invent. - [Alert](https://gesso-docs.vercel.app/components/alert.md): Alert: a persistent inline banner, with the three tones the palette has, the paint that keeps a banner proportional, and the role it declares. - [Checkbox](https://gesso-docs.vercel.app/components/checkbox.md): Checkbox: a box the user ticks, controlled or self-managing, with its props, keyboard map and semantics. - [Switch](https://gesso-docs.vercel.app/components/switch.md): Switch: an on and off control with the checkbox's behaviour and the switch's role, plus its props, keyboard map and semantics. - [RadioGroup](https://gesso-docs.vercel.app/components/radio-group.md): RadioGroup: one choice from a few, as a single tab stop whose arrows move the choice, with its props, keyboard map and semantics. - [SegmentedControl](https://gesso-docs.vercel.app/components/segmented-control.md): SegmentedControl: one choice from a few as a single track cut into segments, with why it is a radio group rather than a tab list, its props, keyboard map and semantics. - [TextInput and TextArea](https://gesso-docs.vercel.app/components/text-input.md): The text field and its multiline twin: the value, the validation message, the editing the field arrives with, and what it announces. - [RichTextEditor](https://gesso-docs.vercel.app/components/rich-text-editor.md): RichTextEditor: markdown edited as formatted text, with the slash menu, completions an application supplies for mentions or anything else, a source view, and RichTextView to show the result. - [Slider](https://gesso-docs.vercel.app/components/slider.md): A value chosen from a range: the props, the keys, the drag, and what a slider announces about itself. - [RangeSlider](https://gesso-docs.vercel.app/components/range-slider.md): A span chosen from a range with two thumbs: the props, the keys for each thumb, the drag that picks a thumb, and what each thumb announces about itself. - [NumberInput](https://gesso-docs.vercel.app/components/number-input.md): A number typed or stepped: the props, the two step buttons, what happens to text that is not a number yet, and what it announces. - [DataTable](https://gesso-docs.vercel.app/components/data-table.md): A table of any length: columns the rows share with a sticky header, sorting from the header or from the application, and a chosen row that survives a sort. - [DataGrid](https://gesso-docs.vercel.app/components/data-grid.md): An editable spreadsheet grid of any size: windowed on both axes, a frozen header, frozen rows and columns, row headers, resizable columns, formulas, an active cell the keyboard walks, a range of cells to select, copy and paste, and a cell editor that opens in place. - [Tree](https://gesso-docs.vercel.app/components/tree.md): Nested data as a list of rows: the open branches, the chosen key, the arrow keys ARIA specifies, and the level every row carries. - [LazyList](https://gesso-docs.vercel.app/components/lazy-list.md): A list of any length whose visible rows are the only ones that exist: the window, the estimate, the revision, and a keyboard that walks the whole list. - [Tabs](https://gesso-docs.vercel.app/components/tabs.md): Tabs: a strip of tabs and the panel under it, with its props, the keys that move the selection, and what it announces. - [Accordion](https://gesso-docs.vercel.app/components/accordion.md): Accordion: sections that open and close, with its props, its two keys, and what an open section announces. - [Card](https://gesso-docs.vercel.app/components/card.md): Card: a bordered surface with an optional heading, and the group it announces around whatever you put on it. - [Divider](https://gesso-docs.vercel.app/components/divider.md): Divider: a one pixel rule between things, on either axis, announced as a separator and named by nothing. - [Toolbar](https://gesso-docs.vercel.app/components/toolbar.md): Toolbar: a bordered row of controls that belong together, announced once as a group rather than as loose buttons. - [Dialog](https://gesso-docs.vercel.app/components/dialog.md): Dialog: a window that takes the keyboard, with its props, the focus trap, Escape, and the overlay layer it draws into. - [Drawer](https://gesso-docs.vercel.app/components/drawer.md): Drawer: a panel that slides in from an edge of the window, modal or beside the page, with its props, keys, semantics and the motion it uses. - [Menu](https://gesso-docs.vercel.app/components/menu.md): Menu: a list of commands anchored to a button or opened at a point, with its props, the keys that walk it, and what it announces. - [Select](https://gesso-docs.vercel.app/components/select.md): Select: one value chosen from a list that is not always on screen, operable from the keyboard alone, with its props, keys and listbox semantics. - [Combobox](https://gesso-docs.vercel.app/components/combobox.md): Combobox: a value chosen by typing, a text field that filters a list, for one value or several, with its props, keys and active-descendant semantics. - [DatePicker](https://gesso-docs.vercel.app/components/date-picker.md): DatePicker: a calendar date chosen from a month, as a YYYY-MM-DD string, operable from the keyboard alone, with its props, keys and grid semantics. - [Tooltip](https://gesso-docs.vercel.app/components/tooltip.md): Tooltip: a label that appears beside a control after a pause, as a modifier on the element or a component around it. - [Popover](https://gesso-docs.vercel.app/components/popover.md): Popover: a non-modal panel anchored to its trigger, with its props, light dismiss, where focus goes, and what the trigger and the panel announce. - [Toast](https://gesso-docs.vercel.app/components/toast.md): Toast: a transient notice drawn over the app, announced through its role rather than by taking focus. - [SplitPane](https://gesso-docs.vercel.app/components/split-pane.md): SplitPane: two panes and a divider the user can drag or arrow, reported as a fraction of the container. - [FindBar](https://gesso-docs.vercel.app/components/find-bar.md): FindBar: the bar Ctrl+F opens over a Gesso app, stepping the matches a find session found. - [MenuBar](https://gesso-docs.vercel.app/components/menu-bar.md): MenuBar: titles along a strip, focus that stays on the bar while a panel is open, and the reason that is not Menu. - [Breadcrumb](https://gesso-docs.vercel.app/components/breadcrumb.md): Breadcrumb: the trail of where you are, the one crumb that is not a link, and what a trail too long to draw does instead. - [NavigationRail](https://gesso-docs.vercel.app/components/navigation-rail.md): An application's destinations down its side: the active one marked current, filled or outline icons, badges, groups that open, close and disable, an icons-only form, Cmd-click to open a destination somewhere new, operated from the keyboard as one tab stop. - [Pagination](https://gesso-docs.vercel.app/components/pagination.md): Pagination: the strip of page numbers under a table, the arithmetic that decides which of them are drawn, and the names that make it usable without looking at it. - [Image](https://gesso-docs.vercel.app/components/image.md): Image: a picture fetched and decoded off the main thread, with its props, its fits, and what it announces. - [Avatar](https://gesso-docs.vercel.app/components/avatar.md): Avatar: a person or an entity as a picture, with the initials and the glyph it falls back to, its sizes, shapes and semantics. - [Video](https://gesso-docs.vercel.app/components/video.md): Video: a moving picture decoded in the render worker, its playback surface, and the props that control it. - [VideoPlayer](https://gesso-docs.vercel.app/components/video-player.md): VideoPlayer: a clip with a play button, a scrubber and captions, built out of ordinary controls against the video transport. - [Icon](https://gesso-docs.vercel.app/components/icon.md): Icon: a glyph rasterised from a path, why its colour is baked into its pixels, and what it announces. - [Spinner](https://gesso-docs.vercel.app/components/spinner.md): Spinner: an indeterminate busy indicator, what it costs per turn, and why it keeps turning under reduced motion. - [ProgressBar](https://gesso-docs.vercel.app/components/progress-bar.md): ProgressBar: determinate and indeterminate progress in one control, its range, and the value it reports. - [Meter](https://gesso-docs.vercel.app/components/meter.md): Meter: a measurement inside a known range, its three bands, and why it is not a progress bar. - [Skeleton](https://gesso-docs.vercel.app/components/skeleton.md): Skeleton and SkeletonText: grey stand-ins with the same box as the content they wait for, with their props, the shimmer and its reduced-motion behaviour, and semantics. ## Recipes - [A settings page](https://gesso-docs.vercel.app/recipes/settings-page.md): A settings screen built from the component library: grouped controls, one cell behind all of them, and one setting that disables another. - [A dialog flow](https://gesso-docs.vercel.app/recipes/dialog-flow.md): Deleting a row behind a confirmation, driven by the keyboard alone, with the focus handed back on cancel and moved deliberately on confirm. - [An appearance setting](https://gesso-docs.vercel.app/recipes/appearance-setting.md): An app that owns its own light, dark and system setting, resolved against what the shell reports and provided as the root's theme. - [Loading, failing, and saving](https://gesso-docs.vercel.app/recipes/loading-and-saving.md): A screen that loads, fails, retries and saves: a keyed request, an optimistic write, and the five status words every screen uses. - [A table over 100,000 rows](https://gesso-docs.vercel.app/recipes/large-table.md): A table over a hundred thousand rows: generated data, sortable columns, a sticky header, a chosen row, and what stays mounted while the reader scrolls. - [A virtualized feed](https://gesso-docs.vercel.app/recipes/virtualized-feed.md): A feed that grows at both ends: a count and a revision as the whole data source, entries that size themselves, a jump to the newest, and what a prepend does to where the reader was.