Build native apps with Tarve
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 95 built-in components.
Getting started
Install
Tarve needs Bun 1.4+ on Windows x64 or Linux x64.
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.
Components
Window & layout
Windows, flex containers, scrolling regions and the primitives every screen is built from.
Text & media
Parley-shaped text, typography presets, images, icons and declarative SVG.
Inputs & forms
Text editing with IME and undo, choice controls, dates and form structure.
Actions & feedback
Buttons, status indicators, notifications and empty states.
Overlays
Modal and non-modal surfaces: dialogs, sheets, popovers, menus and command palettes.
Navigation
Tabs, menus, sidebars and other ways to move around an app.
Data display
Lists, virtualized collections, tables, grids, trees and charts.
Rich content
Native leaves for large documents: Markdown, highlighted code and diffs.
App & chat
Building blocks for chat, assistant and onboarding interfaces.
Common props
Every component accepts these props in addition to its own.
| Prop | Type | Default |
|---|---|---|
children Content rendered inside the component. | Child | — |
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 | — |
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 | — |
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 | — |