Try it live: toolback.netlify.app
A modern ToolBook spiritual successor: book → pages → objects, authored visually, scripted in plain JavaScript. If you ever built something in ToolBook or HyperCard, you'll feel at home — everything else is 2026.
Books are open data (a single .toolback.json), editing is local-first
(an autosave in IndexedDB keeps nothing hostage), and publish produces one
self-contained HTML file you can drop anywhere. No backend, no build step for
your books, nothing to install for your readers.
ToolBook (and HyperCard before it) had something that the modern web lost: the author and the reader were the same person, five minutes apart. Click a button into existence, script it in a language that fit on one screen, and press a key to play. Publishing was "save a file". A kid could make something and deploy it before lunch.
Authoring tools today are a hellscape by comparison — a login, a cloud subscription, a wall of panels, an SDK version matrix, a two-stage pipeline, a build step that needs its own conference talk, and a platform that decides to deprecate your "simple" app every six months. Nothing you make is yours, and nothing stays small.
toolback is the counter-move, driven by nostalgia and intent:
- Easy to use again — drag-and-drop authoring, a visible canvas, one screen of sensible panels. Design and run share one space; F3 / ⌥3 flips between them like the ToolBook of old.
- Easy to deploy again — Publish writes a single standalone
.htmlwith everything (player, your book, even npm libraries) baked in. Host it on any static server, stick it in apublic/folder, email the file. There is no "backend" and no "production environment". - Modern under the hood — scripts are plain JavaScript: no dialect, no macro language, no 1990s scripting school. The editor's IntelliSense is curated to exactly what your book can use, and books run in a sandboxed canvas that keeps even the most broken script from taking the editor down.
- Open and yours — books are JSON, which means they're git-diffable, grep-able, and portable. There's no locked format and no cloud lock-in.
ToolBook heritage is everywhere in the model (the self / target /
forward() event chain, backgrounds as shared page resources, popups, F3 run
toggle) — but the words you type are JavaScript.
- Author visually — drag controls (button, label, input, image, card, container, switch, group, markdown, html) onto a canvas with a 8px grid; resize, arrange, group/ungroup, duplicate; per-breakpoint layouts for desktop / tablet / mobile.
- Script in plain JS — object event scripts, page scripts, background scripts, and full IntelliSense (Ctrl+Space) that only offers things that actually exist in your book. Red squiggles catch syntax errors before you press Run.
- The ToolBook event model — an explicit owner chain, not DOM bubbling:
the innermost handler runs and stops unless you call
forward().self= the object whose script you're writing,target= what was clicked. - A store that's data, not code — keep design values in the Book tab, seed
every run from them, and watch live
store.set()swhile a run is going.{{key}}labels resolve right in the design view. - Pages, navigation & popups —
page.go('Results'),page.enterlifecycle, and any page opening any other as a floating dialog. - Backgrounds — the classic shared-page trick: one background's objects appear on every page that uses it, a perfect home for a nav bar.
- Author-mode plugins — a page flagged Plugin page can run as a floating
tool while you author, driving the editor through a small
authorbridge. Everything a plugin does is ordinary undoable book history. - Build with AI — describe an app in plain words and a model writes a toolback book: it's validated and smoke-run for script errors, then added as pages, used to extend the current page (existing objects kept intact), or swapped in for the project. Bring your own key — DeepSeek, OpenAI, Anthropic, Groq, OpenRouter, Gemini, Mistral, Together, xAI, OpenCode Zen/Go, or local Ollama / LM Studio. See llm-authoring.md.
- npm libraries in books —
await import('@tonejs/midi')just works (esm.sh at runtime, or pre-bundled onto a local "library shelf" for fully offline publishes). The kitchen-sink example builds a two-note MIDI in-browser. - Undo/redo, duplicate, Copy JSON — whole-book snapshot history, duplicate
cascades, and
{ } JSONon the selection for inspecting structures. - Publish — one click → a single self-contained
.htmlstanding alone.
See the full scripting guide — everything a script can do, with copy-paste recipes. For how it works under the hood (architecture, the editor↔canvas message protocol, the file-link sync engine): runtime-internals.md.
Debugging feels like the web, because it is the web:
- Status bar errors — script failures appear in the editor's status bar,
tagged with where they came from (
button1.click: Error: …,page script: SyntaxError: …), with a ✕ to dismiss. - Browser devtools (F12) — open devtools and pick the canvas frame's
context; any
console.log(...)in your scripts lands there. Your scripts run in a sandboxed iframe, so they can't take the editor down — but you can still inspect them for real. - Live Store tab — during a run, the Store tab is a live stream: every
store.set()shows up as it happens, and each row's ⇓ copies the live value into the design store for the next run. A live-coding loop. - Edit scripts in VS Code — every script editor has a ⇄ file button:
link the script to a real
.jsfile on disk and edit it in VS Code (or anything). The sync is two-way and carefully race-proofed — type in the editor, save in VS Code, either way the book and the file stay in step. ⤢ pops the editor out into a resizable floating window. Markdown/HTML viewer fields get the same ⇄ file / ⤢ pair (.md/.htmlfiles).
A pnpm monorepo — dependencies run format ← controls ← runtime ← editor.
apps/editor/ the editor app — Vue 3 + Pinia + Monaco
packages/
format/ @toolback/format — book/page/object zod schemas + factories
controls/ @toolback/controls — plain-DOM control renderers, zero framework
runtime/ @toolback/runtime — the player: no Vue. Renders JSON,
runs scripts, editor↔canvas protocol
libs/ @toolback/libs — the "library shelf" for npm-in-books
examples/ ready-made .toolback.json books + a test that runs every page
docs/ scripting-guide.md (author-facing), runtime-internals.md,
llm-authoring.md (AI authoring spec), screenshots/
plans/ internal design notes & the milestone/progress log
The editor is the single source of truth for the book; the canvas runs the same runtime used for publishing, inside a sandboxed same-origin iframe — so design mode and run mode share one thing, and broken user scripts can never crash the editor.
Requires pnpm (enable it with corepack enable if you don't
have it). Node 20+.
pnpm install # install workspace deps
pnpm dev # editor dev server → http://localhost:5173
pnpm test # vitest across packages, apps and example books
pnpm typecheck # tsc / vue-tsc across the monorepo
pnpm build # production buildHungry for a quick tour? Open an example book with File → Open… and press Run (F3 or ⌥3):
examples/hello-counter.toolback.json— the classic first bookexamples/quiz.toolback.json— navigation + a score in the shared storeexamples/kitchen-sink.toolback.json— an 8-page guided tour of every featureexamples/author-plugin.toolback.json— an author-mode plugin driving the editor
(More detail on each in examples/README.md.)
The editor is a fully client-side app — deploy it to any static host, including
Netlify, gh-pages, or a plain nginx folder:
- Build:
pnpm install && pnpm build - Publish:
apps/editor/dist
A netlify.toml and a pnpm-lock.yaml are included, so a Netlify deploy with
Base directory: / and Build command: pnpm install && pnpm build works
out of the box. Because everything is local-first, an exported book
(.toolback.json or a published .html) runs from any static host without a
server of any kind.
The File System Access API used by Open…, Save and ⇄ file linking requires a secure context (HTTPS) and a Chromium browser — on Netlify's HTTPS that's just how it works. Non-supporting browsers fall back to classic file dialogs for open/save.
M0–M6c (core authoring, scripting, pages/popups/backgrounds, groups, store, npm-in-books, author plugins) are complete, along with copy/paste, responsive edge constraints (follows left/right/both/centred), npm library support, and AI authoring (generate / extend / edit / replace a book from a prompt, with validation, a runtime smoke-run and repair). The full plan, architecture and milestone log live in plans/PLAN.md; the architecture reference is docs/runtime-internals.md.
