🌐 Landing page — the screenshot tour, scroll by scroll.
A tiny desktop companion for tinyjs — create tinyjs apps and turn websites into desktop apps, without opening a terminal. Built with tinyjs itself, which makes it the two things at once:
- A living demo for developers. Everything here is stock tinyjs — a native
window, the bridge pushing streamed subprocess logs to the page, native
folder pickers driving the UI, a JS backend with full process access in a
few hundred lines. Read
src/as the tutorial. - A gentle on-ramp for newcomers. Pick a folder, name your app, click Create, watch the logs, hit Run. No shell required. The Wrap tab turns any website into a real desktop app the same way.
Built by @slabbdev. Not an official tinyjs project — just what its author considers the demo tinyjs deserved. 🙂
Wrap any site. Paste a URL, pick your window modes, watch the preview mirror every option — then generate a ~6 MB desktop app with its own icon, per-origin API gate, downloads and popup handling.
Menu-bar apps, live. Menu-bar mode puts a tray icon in the system menu bar — click it and a dropdown panel anchored under the icon opens the site (tray click can also open a normal window):
Real windows, really wrapped. The generated apps are ordinary desktop windows — frameless or not, with whatever chrome you configured:
Everything in one place. Projects sidebar (with a file tree per project), live preview stage, config inspector — sections Site, Window, Behavior.
The file offcanvas. Click a file in a project's tree: images open as a preview, code files open in an editor with line numbers, code folding and syntax highlighting (CodeMirror 6, vendored) — edit and save right there.
iPhone mode. The iPhone user-agent preset also reshapes the preview into a phone frame — you see the mobile layout before you wrap:
- Create an app — runs
tinyjs newfor you: the zero-dependency vanilla templates, or a Vite + npm one (react/vue/svelte/solid, TypeScript). - Wrap a website — runs
tinyjs wrap: a site becomes a real desktop app (native window, downloads, popup handling) whose pages get no access to your machine beyond their own window and dialogs — that gate is tinyjs' per-origin API policy, not a Studio promise. - Open an existing project — point the Studio at any tinyjs project folder anywhere on disk; it joins the sidebar with all its actions, no files moved.
- Run, build, stop, duplicate, reveal — drive
tinyjs dev/tinyjs buildon the selected project, with every line of the CLI streamed live into the window.
None, really. Open the app: it checks for the tinyjs CLI, and if it's missing, one click runs the official installer with every line streamed into the console (macOS / Linux / Windows; on Linux the installer explains the WebKitGTK runtime if it's missing). The Studio drives the installed CLI by absolute path — no PATH editing, nothing else touched.
- wrap is newer than any tinyjs release: until it ships upstream, the Wrap tab reports not in this release yet and Create / Run / Build carry on. The status bar shows whether your tinyjs has wrap.
- Developing on wrap? A tinyjsapp checkout is picked up automatically (see
below) — or set
TINYJS_BIN.
The Studio finds the CLI in this order:
TINYJS_BINenvironment variable- a
tinyjsappsource checkout next to this repo (../tinyjsapp,../tinyjsapp-cli) - the installed CLI (
~/.tinyjs/tinyjs,%LOCALAPPDATA%\tinyjs\tinyjs.cmd, orPATH)
The resolved binary, version and wrap support show in the window's status bar.
git clone https://github.com/slabbdev/tinyjsapp-studio
cd tinyjsapp-studio
tinyjs devShip it like any tinyjs app: tinyjs build packages the whole Studio in a
few megabytes (a signed .app on macOS, binaries on Windows/Linux). No
Electron in sight, because there is no bundled browser: tinyjs renders with
the WebKit (or WebView2) your OS already has.
- tinyjs by
Tarwin Stroh-Spijer — the tool, the runtime,
and the
wrapplumbing this Studio drives. Docs at tinyjs.app. - The wrap command itself is being contributed upstream; this repo consumes it, it does not reimplement it.
If the Studio saves you a click, a coffee is appreciated ☕







