Tarve documentation
Everything you need to ship a native Windows and Linux interface from Bun and TSX: setup, the rendering model and a reference page for each of the 97 built-in components.
Getting started
Install
Tarve needs Bun 1.4+ (or Node.js 26.10+) on Windows x64 or Linux x64. From there you also build for Android.
terminal bun add @tarve/core bun add -d typescript @types/bunConfigure TypeScript
Point the JSX runtime at
@tarve/core.tsconfig.json { "compilerOptions": { "target": "ESNext", "module": "ESNext", "moduleResolution": "Bundler", "strict": true, "jsx": "react-jsx", "jsxImportSource": "@tarve/core", "types": ["bun", "@tarve/core/assets"] } }Write a window
app.tsx import { Button, Column, Text, Window, createApp } from "@tarve/core"; let count = 0; function App() { return ( <Window title="Counter" width={520} height={360}> <Column flex={1} align="center" justify="center" gap={16}> <Text size={42} weight={700}>{count}</Text> <Button onClick={() => count++}>Increase</Button> </Column> </Window> ); } const app = createApp(App); await app.ready; await app.closed;Run and ship
terminal # runs the source directly, no build step bun app.tsx # Windows → .exe with the native runtime embedded bun run tarve build app.tsx --outfile dist/App.exe # cross-compile for Linux x64, no Rust toolchain needed bun run tarve build app.tsx --target linux-x64 --outfile dist/App
How rendering works
Your view is a plain function that returns TSX. Tarve compiles it into a retained tree, diffs it against the previous one and sends only the changed nodes to the native runtime, where Taffy lays them out and Vello, D3D11 or the CPU renderer paints them.
State can live in ordinary variables. When a native event handler such as onClick or onChange runs, Tarve schedules a re-render automatically. For changes that happen outside an event (timers,
network responses, file watchers) call app.update() on the handle returned by createApp.
Controls are controlled: pass the current value (checked, value, open…)
and update it in the matching on…Change callback. An idle window presents zero frames.
For values that change many times a second (a clock, a progress bar, an animation), use a signal().
Passed as a text child or a style value, it is bound to that node: setting count.value sends only that
field to the native runtime, with no render, diff or layout when the size stays the same. batch() groups
several changes into one update, and <audio time={position}> writes the playback position into a signal.
import { Text, Window, createApp, signal } from "@tarve/core";
const time = signal(new Date().toLocaleTimeString());
setInterval(() => { time.value = new Date().toLocaleTimeString(); }, 1000);
createApp(() => (
<Window title="Clock">
<Text size={48}>{time}</Text>
</Window>
));<Scroll followTail> keeps a chat or a log at its end while content grows, until the user scrolls away; app.scrollTo(id, { y: "end", smooth: true }) scrolls a Scroll after the next layout.
Style anything with the style prop or with Tailwind classes: class="flex gap-2 p-4 hover:bg-muted" compiles to the same native style, with no CSS involved.
Components
Window & layout
Windows, flex containers, scrolling regions and the primitives every screen is built from.
Window The root of every Tarve app: a native OS window with size, position and theme.
TitleBar A custom, draggable title bar with native minimize, maximize and close controls.
View The base box. Flexbox/Grid layout, styling and events for anything you render.
Row A View that lays its children out horizontally.
Column A View that lays its children out vertically.
Scroll A native scroll container with vertical, horizontal or two-axis scrolling.
ScrollArea A scroll container with themed scrollbars, ready for panels and lists.
Portal Renders its children above the rest of the window, outside the parent's clipping.
Pressable A headless interactive surface: click, hover, keyboard and context-menu events.
Resizable Two panels separated by a draggable, keyboard-accessible splitter.
AspectRatio Keeps its content at a fixed width-to-height ratio.
Direction Switches a subtree between left-to-right and right-to-left flow.
Separator A thin horizontal or vertical divider line.
AnimatePresence Keeps a child mounted while its native exit animation runs.
Glass Liquid Glass: a refracting, blurring surface for toolbars, tab bars and floating controls.Text & media
Parley-shaped text, typography presets, images, icons and declarative SVG.
Text Native, Parley-shaped text with size, weight, colour and selection.
Typography Preset text styles: headings, lead, muted, code and blockquote.
Link A native hyperlink that opens through the platform's URI handler.
Label A form label with required and disabled states.
Kbd Renders a keyboard key or shortcut.
Image Displays files, URLs, encoded bytes or raw RGBA pixels.
Svg A declarative SVG canvas rendered natively.
Path An SVG path element.
Circle An SVG circle element.
Ellipse An SVG ellipse element.
Line An SVG line element.
Polyline An SVG polyline element.
Polygon An SVG polygon element.
SvgRect An SVG rect element.Inputs & forms
Text editing with IME and undo, choice controls, dates and form structure.
Input A single-line native text field with IME, selection and undo/redo.
TextArea A multi-line native text editor.
InputGroup Wraps an input with leading and trailing adornments.
InputOTP A segmented one-time-code input.
Field Label, description and error message around a form control.
Checkbox A labelled, controlled checkbox.
Switch A labelled on/off toggle switch.
RadioGroup A set of mutually exclusive options.
Select A themed dropdown for choosing one option.
NativeSelect A compact select with native-feeling keyboard behaviour.
Combobox A searchable select with filtering and keywords.
Slider Picks a number from a range by dragging or with the keyboard.
Toggle A two-state button, like bold in a text toolbar.
ToggleGroup A row of toggles with single or multiple selection.
Calendar A month grid for picking a date, with min/max and disabled days.
DatePicker A button that opens a Calendar popup.Actions & feedback
Buttons, status indicators, notifications and empty states.
Button The primary action control, with variants and sizes.
ButtonGroup Joins related buttons into one segmented control.
Badge A small status or count label.
Progress A determinate progress bar.
Spinner A loading indicator drawn by the renderer.
Skeleton A placeholder block for content that is still loading.
Alert A highlighted message with title, description and icon.
Toast A single transient notification.
Toaster Stacks and positions a list of toasts you control.
Empty An empty state with icon, message and call to action.Overlays
Modal and non-modal surfaces: dialogs, sheets, popovers, menus and command palettes.
Modal A modal dialog with title, description, body and footer.
Dialog Alias of Modal, named after the shadcn convention.
AlertDialog A confirmation dialog with cancel and action buttons.
Sheet A panel that slides in from any edge of the window.
Drawer A Sheet that defaults to the bottom edge.
Popover Floating content anchored to a trigger.
Tooltip A short hint shown next to its trigger.
HoverCard Rich preview content shown while hovering a trigger.
DropdownMenu A menu of actions opened from a trigger.
ContextMenu A right-click menu attached to a region.
Command An inline, searchable list of commands.
CommandPalette A modal command search, the classic Ctrl+K palette.Navigation
Tabs, menus, sidebars and other ways to move around an app.
Tabs Switches between panels of content.
Accordion Vertically stacked sections that expand one at a time.
Collapsible A single section that shows and hides its content.
Breadcrumb Shows the path to the current location.
Pagination Page navigation with previous, next and numbered pages.
NavigationMenu Top-level navigation with dropdown link panels.
Menubar A desktop-style menu bar: File, Edit, View…
AppMenuBar The window's application menu bar, with access keys, accelerators and submenus; what app.menuBar draws.
Sidebar A collapsible app sidebar with icons and badges.
Carousel Steps through slides with buttons and indicators.Data display
Lists, virtualized collections, tables, grids, trees and charts.
Card A bordered container with title, description and footer.
Item A list row with title, description and leading/trailing slots.
List A simple, non-virtual list where every item stays mounted.
VirtualList Renders only visible rows: fixed, measured or externally windowed.
Table A static table built from column definitions.
DataTable A Table with clickable rows and an empty state.
DataGrid A virtualized grid with sorting, filtering and selection.
TreeView A keyboard-navigable tree with expand and select.
Chart A simple native bar chart.Rich content
Native leaves for large documents: Markdown, highlighted code and diffs.
App & chat
Building blocks for chat, assistant and onboarding interfaces.
Message A chat message with avatar, author, timestamp and actions.
Bubble The speech bubble used inside a message.
MessageScroller A scroll container for a conversation.
Marker A labelled divider, such as a date between messages.
Attachment A file chip with upload progress and remove action.
Questionnaire A step-by-step form with text, single and multiple choice.Common props
Every component accepts these props in addition to its own.
| Prop | Type | Default |
|---|---|---|
children Content rendered inside the component. | Child | — |
class Same as `className`, HTML spelling. Both may be given; `className` comes last. | string | — |
className Tailwind utility classes, compiled to `style` at the call site; an explicit `style` wins. | string | — |
draggable | boolean | — |
dropTarget | boolean | — |
fileDropTarget | boolean | — |
highlight Highlights text matches inside the node, as used by find-in-page. | TextHighlight | — |
id Stable native node id. Used for focus, scrolling, tests and accessibility; popups derive their part ids from it. | string | — |
key Reconciliation key that keeps list items stable between renders. | string | number | — |
motionFrom Initial numeric values for a native enter transition. | MotionValues | — |
onDragEnd | (event: DragEndEvent) => void | — |
onDragEnter | (source: string) => void | — |
onDragLeave | (source: string) => void | — |
onDragMove | (event: DragMoveEvent) => void | — |
onDragStart | (position: DragPosition) => void | — |
onDrop | (event: DropEvent) => void | — |
onFileDragEnter Files entered the node; `paths` are the dragged files. | (paths: string[]) => void | — |
onFileDragLeave | () => void | — |
onFileDrop | (event: FileDropEvent) => void | — |
onHighlight Reports how many highlight matches were found. | (event: { matchCount: number }) => void | — |
onPaste Receives non-text clipboard content (files or a bitmap) pasted while focused. | (payload: PastePayload) => void | — |
onPointerLeave The pointer left this node and its children (DOM `pointerleave`). | () => void | — |
onPointerMove Pointer position inside this node (like DOM `offsetX`/`offsetY`) while it is over it or its children. | (point: { x: number; y: number }) => void | — |
onSize Content-box size after layout, on mount and whenever it changes (a ResizeObserver). | (size: { width: number; height: number }) => void | — |
onTransitionEnd Called when a native transition finishes on a property. | (event: { property: MotionProperty }) => void | — |
rovingGroup Joins a roving-focus group so arrow keys move focus between siblings. | boolean | — |
style Layout, colour, border, shadow, gradient, transform and transition styles, plus hover/focus/active/disabled state styles. | Style | — |


