Strata is pre-1.0. APIs, protocol, and storage format may change.
Strata
Route live
A typed collaboration stack for Gleam applications, powered by CRDTs and the BEAM.
- Runtime
- BEAM · single node
- Protocol
- v0 · shared codec
- State
- CRDT · persisted
- Release
- pre-1.0
Self-hosted typed collaboration infrastructure for Gleam.
SR-01 V0 SESSION ROUTER
Client alice · browser
Server edge upgrade accepted
Document channel doc:kanban
Shelf ETS → DETS
Peer bob · browser
FRAME 01 welcome
Server edge → Client {
"v": 0,
"kind": "welcome",
"session_id": "s-4f2a",
"server": "strata-1"
} The server authenticated the socket. It sends the session ID before document traffic begins.
Real v0 frame shapes. Example ids and values.
Inside the route
- The server authenticates the upgrade. The client sends
?token=…on the WebSocket URL. The server compares it withSTRATA_TOKENin constant time. It returns HTTP 403 for an invalid token. - One store actor owns document state. The actor keeps documents keyed by ID,
merges ORMap state, and coordinates persistence. beryl manages each socket and
doc:<id>topic join. - Join with a snapshot; continue with deltas. A join or reconnect receives
a snapshot. Each later
deltaframe contains encoded ORMap state. - The server merges, writes, then broadcasts. The server merges state with
lattice_crdtand writes it to shelf. It then usesberyl.broadcast_fromto send the state to the other sockets. - Presence is separate from the document. Cursors, selections, names, and colors live in a per-document add-wins set and vanish with the socket.
- Client and server share one codec.
strata_protocolcompiles for Erlang and JavaScript, so frames cannot drift between the two ends.
When to use Strata instead of beryl
beryl provides the transport: typed real-time
channels, presence, and a Phoenix-Channels-compatible wire format. Its collab_docs
example shows how to build a CRDT application directly. Strata packages that pattern as a
typed stack with a server, client, document schemas, component contracts, transports,
persistent storage, and an admin interface.
| Concern | beryl + collab_docs | Strata |
|---|---|---|
| Wire protocol | Two ad-hoc events per app | Versioned v0 envelope shared by client and server |
| Sync model | Whole-state merge on every edit | Snapshot on join; encoded ORMap state on later edits |
| Persistence | In-memory Dict, lost on restart | shelf ETS + DETS with periodic flush and schema-validated decoders |
| Runtime model | Application-owned example state | Supervised channels plus a durable document Store actor |
| Auth | HMAC token in the join payload (example code) | Shared secret checked on the WebSocket upgrade; JWT slots in later |
| Client | None; each application implements a client | strata_client, transport-agnostic, Erlang and JavaScript |
| Admin | None | Read-only Lustre SPA at /admin: docs, sizes, sockets, presence |
| Configuration | Hard-coded in the example | StrataConfig: rate limits, persistence, static assets |
The stack
| Package | Target | Purpose |
|---|---|---|
| strata_protocol | Erlang · JS | Frame types and JSON codecs |
| strata_document | Erlang · JS | Typed CRDT fields, records, and document IDs |
| strata_server | Erlang | mist + beryl + shelf server runtime |
| strata_client | Erlang · JS | Sans-IO client state machine |
| strata_component | Erlang · JS | Headless components, typed ports, and bindings |
| strata_transport | JS | Browser WebSocket transport |
| strata_transport_gun | Erlang | Gun-backed transport |
| strata_admin | JS | Read-only Lustre admin SPA |
Built on beryl, lattice, shelf, and mist. Strata packages are not on Hex. Build them from source.
Release state: pre-1.0
Works today
- Single-node server, delta sync, presence, persistence across restarts
- Typed documents, composition, and headless component contracts
- The full v0 frame set on both targets
- Reconnect, demonstrated in the bundled examples
- Read-only admin, per-socket rate limits
- Target-specific unit tests and Playwright tests for the examples
May change
- Wire protocol (versioned, no compatibility promise yet)
- Public package APIs
- On-disk storage format
Run it locally
git clone https://github.com/tylerbutler/strata.git
cd strata
mise install && just deps && just build-all
just example kanban # http://localhost:8000 in two tabs