Step 1: What you're building
A pile of wooden letter blocks, shared live — then two separate boards that don't touch each other's blocks.
Let's say you're making a world where you're running two campaigns at once — The Salt Road and Winterhold — and you needed a tabletop toy each table could fidget with mid-session, without one table's blocks getting shoved around by the other's. Here's how you build that.
Here's the finished thing. Drag a block. Grab a handle to rotate or scale it. Tap one to tumble it to a new face:
Drag the letters around. Their positions are shared state, so a second person sees your blocks move. The clacking sound needs the platform's audio engine, which a docs page doesn't run.
That's real — every block's position is shared state, the same as everything else you've built on this site. What it doesn't show you yet is the part this page is actually about: open it once for The Salt Road and once for Winterhold, and you get two boards, one per table, not one board both campaigns are fighting over.
That's the new idea. An app doesn't run once per world — it runs once per project, and a project is a real, running instance of your app: its own board, its own name, reading the same world everything else reads.
You will learn
- Why an app runs once per project instead of once per world
- How
vvd runasks which instance to open — and how your app can ask the same question useCollabState, the hook that gives your app a shared document with no coordinates to pass- How to read the world's look instead of shipping your own, hardcoded one
The version you're building here
The kit above is the polished one — rotate, scale, a tumble sound. This page builds a smaller version of the same idea by hand, one edit at a time, so you see exactly where the "multiple instances" part comes from rather than finding it already wired up. By the end you'll have two of these, side by side, proving neither one knows the other exists:
Drag a letter. Nothing is faked — useCollabState is the same shared-document machinery
every tool on this site runs on, and you'll build this exact file by hand starting at Step 2.
Why the running example is a tool, not the app
The examples on this site mount a tool against a fake host, in your browser. An app
provides a host and owns a route — it needs the real shell, which is what vvd run
gives you. What you can honestly show here is the app's screen, which is a tool like any
other. Apps covers the difference if you haven't met it yet.