Project and dev tools
Scaffold a project with create-tarve, iterate with tarve dev, look inside a running app with the visual inspector, and let AI agents drive it over MCP.
Create a project
create-tarve writes a ready-to-run project: package.json with @tarve/core and the dev, start, build and typecheck scripts, the tsconfig.json, a .gitignore and a README. It has no dependencies and runs on Bun and Node.js 26.10+.
bun create tarve my-app
npm create tarve@latest my-app
# no prompts
bun create tarve my-app --template tailwind --runtime bun --yes
npm create tarve@latest my-app -- --template svelte --runtime node --yes| Template | What you get |
|---|---|
basic | A counter with Window, Column, Text and Button. |
tailwind | The counter styled with Tailwind CSS 4 classes and a light/dark switch. |
svelte | A Svelte 5 counter through @tarve/svelte (app.ts + App.svelte). |
tray | A system tray app with a menu, notifications and hide-on-close. |
| Option | Meaning |
|---|---|
-t, --template <name> | basic, tailwind, svelte or tray. |
-r, --runtime bun|node | Scripts, @types/* and engines for Bun 1.4+ or Node.js 26.10+. Defaults to the runtime running create-tarve. |
--title <title> | Display name; defaults to one derived from the directory. |
-y, --yes | Never prompt. |
-f, --force | Write into a non-empty directory, overwriting files with the same names. |
Development mode
tarve dev runs the entry with hot reload: a saved change remounts the new view into the window that is already open. Under Bun, TARVE_DEV=1 bun --hot app.tsx does the same. Render, handler, listener and hotkey errors replace the view with an in-window overlay showing the source, message and stack; saving a fix remounts the app.
bunx tarve dev app.tsx # Bun
npx tarve dev app.tsx # Node.js 26.10+
bunx tarve run app.tsx # no hot reloadThe native frame-time overlay draws the CPU cost of the last 120 frames against a 16.7 ms budget. It schedules no frames of its own, so an idle window still presents nothing.
const app = createApp(App, { frameOverlay: true }); // or TARVE_FRAME_OVERLAY=1
app.setFrameOverlay(false);Visual inspector
The inspector opens a second window beside your app with the live tree of components and native nodes. Turn it on from the CLI, in code or with an environment variable:
bunx tarve dev app.tsx --inspect # also: tarve run --inspect, npx tarve dev --inspect
TARVE_INSPECTOR=1 bun app.tsxconst app = createApp(App, { dev: { inspector: true } });| Panel | Shows |
|---|---|
| Tree | Components and the native nodes they returned, fragments grouped. ×N is how often a component rendered; a reused memo() does not count. |
| Details | Props of the selected node, its resolved style, its fields and the layout box computed by the native tree. |
| Pick node | Highlights the node under the pointer in the app window; clicking selects it in the tree. Honors paint order, portals, zIndex and scroll clipping. |
| Expand all / Collapse | Opens or folds the whole tree. |
| Event log | Native events as the app receives them. |
The inspector is TypeScript only and uses existing protocol requests; windows opened with app.openWindow never get one of their own. TARVE_INSPECT=<file> is a different switch: automation that writes the tree to a file and exits.
AI agents (MCP)
@tarve/mcp is a Model Context Protocol server: it starts your app with tarve dev and lets an agent (Claude, Cursor, VS Code…) see and drive the real window. Install it with bun add -d @tarve/mcp and add it to the client's config; "args": ["tarve-mcp", "src/app.tsx", "--runtime", "node"] runs the app on Node.js, and a built executable (tarve-mcp dist/App.exe, txiki.js too) runs as it is.
{
"mcpServers": {
"tarve": { "command": "bunx", "args": ["tarve-mcp", "src/app.tsx"] }
}
}| Tools | |
|---|---|
| Read | app_status, inspect_tree, query_nodes, screenshot, wait_for |
| Drive | click, hover, type_text, press_key, scroll, drag, focus: by visible text, id or window point, through native hit testing |
| Develop | reload, get_metrics, get_events, get_logs |
Development only: the app connects out to a private socket the server made, presents a random token, and listens on nothing; there is no eval. A normal launch, or dev: false, never connects.