Abracadabra Server

Real-time sync, no drama.

A single Rust binary that speaks CRDTs, stores documents, authenticates users, deduplicates uploads, and hooks into every phase of its own lifecycle. One command boots it into a live terminal dashboard — or runs it headless as a service.
Realtime database

One server. Every document, live.

The backend that makes the multiplayer real. It speaks documents, not rows — self-host the binary or let us run it for you.

One Rust binary, ~14 MB — Raspberry Pi, Fly.io, or beside your Postgres
Live cursors, presence and CRDT merges in under a millisecond
SQLite for a small team, Postgres for a company — same protocol
MCP clients join as real users, under the same permissions you have
Passkey login, six roles, every upload deduped by SHA-256
REST + WebSocket built in, 34 hook points. MIT, no open-core trap
0documents
0users
0msp99 latency
0ops/s
Actor model

One Tokio actor per document.

Each loaded document owns its own task. Updates arrive in batches of up to 100, flushed to SQLite every 100 ms, broadcast in ~1 ms.

  • Zero locks — DashMap routes to the right actor.
  • Up to 100 updates coalesced per SQL transaction.
  • Broadcasts land on every connected client in under a millisecond.
  • Auto-unload after 300 s idle — reloads on next update.
document_store.rs
live
Binary wire protocol

8 message types. One WebSocket.

Sync, Awareness, Auth, Subdoc, Stateless, Close, SyncStatus, QueryAwareness — all multiplexed over a single connection.

  • VarInt / VarString wire format — compact and fast.
  • Sync uses state vectors — only deltas cross the wire.
  • Multiplex many docs over one connection.
  • SyncStatus acks every applied update.
ws://abra · v2
multiplex
client A
abracadabrasync · auth · broadcast
client B
Sync
Awareness
Auth
Stateless
Subdoc
Query
Status
Close
Identity · RBAC

Six roles, resolved recursively.

Password or Ed25519 challenge-response. JWT in, effective role out — computed through the document tree with a recursive CTE.

  • Passwordless by default — WebAuthn PRF compatible.
  • Inheritance resolved down the parent chain.
  • JWT 7-day (password) or 4-hour (crypto) TTLs.
  • Device sessions + pairing invites for multi-device.
identity · permission
rbac
role hierarchy
Servicebypass all checks
L5
Adminadmin routes
L4
Ownermanage + write
L3
Editorwrite docs
L2
Viewerread + awareness
L1
Observerread only
L0
Ed25519 challenge
POST /auth/challenge
································
32-byte nonce · 60 s TTL
sign(challenge, sk)
································
client-side · private key never leaves device
POST /auth/verify
JWTvalid 4h
server checks signature → issues JWT
Storage

SQLite, or Postgres.

One sqlx-backed storage layer, two dialects. SQLite runs in WAL mode with concurrent readers and a serialized writer — one file, zero ops. Flip the URL to Postgres and writes fan out in parallel under MVCC.

  • SQLite WAL mode — many readers, never blocked by writers.
  • SQLite serializes writes — one writer at a time, engine-enforced.
  • Postgres backend unlocks true parallel writes under MVCC.
  • Flip the URL in [database] — same schema, same API.
database · pool
sqlite · wal
read · 320/32
write · 1IDLE
WALjournal_mode = WAL
Content-addressed storage

SHA-256 is the filename.

Content-addressed uploads deduplicate identical bytes automatically. Reference counts track liveness. Orphans are swept in the background.

  • Same bytes, same blob — twice the refs, zero duplicate disk.
  • Every file identifiable by its 256-bit hash.
  • Orphan sweeper reclaims unreferenced blobs.
  • Path traversal hardened at the storage boundary.
upload_service.rs
dedup
incoming
sha-256
file_blobs · content-addressed
Extension system

Thirty hooks. Native or Wasm.

Drop in custom logic at 30+ points across nine phases: server lifecycle, HTTP, auth, connections, documents, sync, permissions, uploads, snapshots.

  • Native Rust via the Extension trait.
  • Wasm components via wasmtime + WIT.
  • before_update can transform updates in-flight.
  • First error short-circuits the chain.
extension_registry.rs
30+ hooks
POST /docs/:id
on_request
on_auth
on_connect
on_load_document
before_update
on_update
on_stateless
on_upload
response
nativeRateLimit
on_request · <1 msok · 23/100
wasmSchemaValidation
before_updateupdate ✓
wasmWebhook
on_updateidle
Core services

Spaces. Chat. Notifications.

Three first-class services on one stateless wire — a pinned hub space, persistent messaging, and notifications that issue themselves on mention. No extra endpoints, no add-ons to wire up.

  • Every server has a hub — the pinned root space.
  • Chat uses stateless frames — no extra endpoints.
  • Notifications auto-issue on chat mentions.
  • Seeded on boot from [[spaces.seed]].
core · spaces · chat · notify
3 services
Spacesis_hub=true
Hubroot
Teamshared
Personalprivate
Chatchat:send
Notificationsnotify:*
Deploy

One binary. Everywhere.

Cross-compiled statically on every push. Drop on a Pi, ship to Fly.io, run in Docker, leave on a VM.

Linux · x86_64

single binary · ~14 MB

Linux · arm64

single binary · ~13 MB

macOS universal

single binary · ~15 MB

Windows · MSVC

single binary · ~14 MB

Raspberry Pi1 watt
Docker1 line
Fly.io1 region
Bare VM1 ssh

Start your own server.

One command, then point your app at your server. That's it.