Tynd
Desktop apps in TypeScript. One language, native binary, no glue code.
Tynd is a desktop-app framework with a TypeScript backend and a native WebView front-end. Your frontend and backend are both TypeScript. RPC types flow from typeof backend — no codegen, no IDL, no schema file. Build produces a small self-contained binary: ~6.5 MB for the lite runtime, ~44 MB for full (Bun packed).
bunx @tynd/cli create my-appNew here? Start with the 5-minute quickstart — scaffold an app, run it with HMR, ship a binary.
At a glance
- TypeScript top to bottom. Backend, frontend, IPC, config — same language, no codegen.
- Two runtime modes, one API. Start with
lite(~6.5 MB binary, embedded QuickJS). Switch tofullwith one config line when you need Bun’s JIT or native npm bindings. - Native window, zero network. No HTTP server, no loopback TCP port, no firewall prompt. Frontend and IPC ride a native custom scheme.
- 26 OS APIs, identical in both modes —
fs,sql,http,websocket,terminal(real PTY),compute,dialog,tray,menu,notification,clipboard,shell,process,sidecar,singleInstance,shortcuts,keyring,autolaunch,store,updater,workers,app,os,path,tyndWindow, plus typed emitters and streaming RPC. - Zero-copy binary IPC. Multi-MB payloads skip JSON/base64 —
ArrayBufferend-to-end, 5-10× faster than the usual webview-framework binary path. - First-class installers.
.app,.dmg,.deb,.rpm,.AppImage, NSIS, MSI. Build tools auto-download on first build. Built-in code signing + macOS notarization. - Framework-agnostic. React, Vue, Svelte, Solid, Preact, Lit, Angular — anything that outputs a pure SPA.
Why Tynd
Most desktop-app frameworks force you to pick a language for the native side (Rust for Tauri, Go for Wails, or the entire Chromium for Electron). Tynd keeps the native layer invisible: you write TypeScript, you get a native binary.
Backend, frontend, RPC — same language, same types.
lite for a 6.5 MB binary, full for the full Node/Bun surface.
RPC and assets never touch TCP — no loopback port, no firewall prompt.
Every backend, frontend, and OS API with signatures and examples.
How it works
TypeScript backend Native OS window
────────────────────────── ─────────────────────────
export async function greet() ◄── IPC ─ await api.greet("Alice")
events.emit("ready", payload) ─── push ─► api.on("ready", handler)
│
▼
tynd-full — your TypeScript runs on Bun, wrapped in a native host
tynd-lite — your TypeScript runs inside the native host, no extra runtimeFrontend assets and IPC ride a native custom scheme — no HTTP server, no loopback port, no firewall prompt. Multi-MB binary payloads (fs.readBinary, fs.writeBinary, compute.hash) skip JSON entirely via a dedicated binary channel.
Two runtime modes
lite | full | |
|---|---|---|
| JS runtime | embedded QuickJS — ships inside the native binary | Bun, packed into the native binary |
| Hot JS speed | interpreter — fine for IPC glue, slower on tight loops | Bun JIT — often 10-100× faster on CPU-bound JS |
| IPC overhead | in-process, no serialization hop | one serialization hop (OS pipe) |
Tynd OS APIs (fs, http, sql, …) | ✓ | ✓ |
Web-standard globals (fetch, WebSocket, crypto.subtle) | ✓ polyfilled | ✓ native |
JS-level Bun.* / node:* | ✗ | ✓ |
| npm with native bindings | ✗ | ✓ |
| Binary size | smaller (~6.5 MB) | larger (~44 MB, Bun compressed) |
| Startup | faster (everything in-process) | slower (spawns Bun) |
See Runtimes for the full parity table.
Requirements
Bun is required for app developers. Tynd is a Bun-first framework — the CLI, the dev server, and the full runtime all run on Bun. Node.js is not supported as a replacement.
# macOS / Linux
curl -fsSL https://bun.sh/install | bash
# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"End users of your built app need nothing — whichever runtime you shipped is already packed into the distributed binary.