Quickstart
From an empty directory to a live, offline-capable app syncing across two browser tabs. About five minutes.
You’ll need Node.js 22.12+ and a running Docker daemon. Nothing else: the CLI brings up SurrealDB and the sync engine itself.
- Scaffold a project
spky initasks four questions. For this walkthrough answer:Prompt Answer Project name spooky-demoProject kind Full project (Schema + App) Schema template Example (User + Threads + Comments) Package manager whatever you use It writes the project, installs dependencies, generates types and creates the first migration.
- Start the stack
SurrealDB comes up on
:8666, the SSP on:8667, and your app’s dev server starts alongside them. Leave this running. It’s your whole backend.NotePorts 8666 and 8667 need to be free. If one is taken,
spky devtells you which process has it. - Look at the schema
Open
schema/src/schema.surql. This file is the source of truth for everything: your types, your sync rules, your permissions.schema/src/schema.surqlNothing here is Sp00ky-specific. It’s plain SurrealQL.
- Render a live list
Drop this into a component.
useQuerytakes the query and keeps it current.src/Threads.tsxthread.author.usernameis typed, and it came back in the same query as the thread. That’s what.related()does. - Write somethingsrc/NewThread.tsx
The new row appears in the list before the server has confirmed it. No refetch, no cache invalidation, no loading state to manage.
- Watch it sync
Open the app in two browser tabs side by side. Create a thread in one.
It appears in the other immediately. Now open DevTools in the second tab, switch the network to Offline, and create a thread there: it still shows up locally. Go back online and it syncs up on its own.
That’s the whole model. You didn’t write a WebSocket handler, a queue, or a retry.
What just happened
spky dev started SurrealDB plus a sidecar called the SSP. When you write a row, SurrealDB pushes
the change to the SSP, which recomputes only the queries affected by it and writes the result into a
small per-user index table. Your client holds one live subscription on that table, so it learns
exactly which of its queries changed. How it works has the full picture.