▸_ tinyjs github ↗

Desktop apps
for macOS in ~6 MB.

A JavaScript backend with full system access, a native WebKit window, and nothing else. No Electron. No bundled Chromium. No HTTP server. No ports.

curl -fsSL https://tinyjs.app/install | sh
macOS · apple silicon + intel · MIT

Shipped app size

electron
≥ 150 MB
tinyjs
~6 MB

Two files: your backend and a 380 KB window process. The frontend is inlined into the binary. The window is the WebKit already on every Mac.

What you get

zero ports

Page ⇄ backend RPC over a Unix socket in a private temp dir. Nothing listens, nothing collides, nothing to scan.

full system access

Backend runs on txiki.js — files, sockets, processes, FFI, sqlite, fetch, WebSocket.

hot reload

Frontend edits swap into the live window; backend edits restart the process. No build step in dev.

native chrome

Real menu bar (About + Quit included), file panels, alert / confirm / prompt — answered by AppKit, not divs.

signed .app bundles

tinyjs build emits a codesigned, notarization-ready bundle with your icon.

agent-ready

Every project ships a skill file, so coding agents already know the whole API.

Quick start

terminal

tinyjs new myapp
cd myapp
tinyjs dev    # window opens, hot reload
tinyjs build  # dist/myapp.app, signed

src/main.js — the whole backend

export const api = {
  hello: async ({ name }) =>
    `hi ${name}`,
};

in the page

await tiny.api.call('hello', { name });
tiny.menu.set([…]);
await tiny.win.openFile();

how it fits

backend (txiki.js) ◂──▸ launcher (WebKit)
     unix socket · line protocol
                 ◂──▸ your page
     tiny.api.call / tiny.api.on