Skip to content

Overview

Layeron Realtime gives your backend app named rooms and channels for live product experiences: chat, collaborative editors, multiplayer cursors, live dashboards, activity feeds, and user presence.

You declare Realtime once in application code, register it with app.use(...), and call it from route handlers or other backend logic.

Terminal window
import { backend } from "@layeron/core"
import { realtime } from "@layeron/modules"
const app = backend()
const live = realtime({
name: "live",
})
app.use(live)
app.post("/rooms/:roomId/messages", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const roomId = pathSegments[2]
const room = live.room(roomId)
const body = await request.json()
return await room.publish({
type: "message.created",
data: body,
})
})

Realtime covers the live collaboration workflows application developers repeat most often:

  • Rooms for chat, meetings, games, and project spaces.
  • Channels for deployment events, notifications, and live dashboards.
  • Presence for online members, cursors, typing state, selection state, and ephemeral user state.
  • Member lists for showing who is currently in a room.
  • Message history for replaying room activity.
  • Idempotent publish calls for retry-safe message creation.
  • Room metadata for titles, modes, permissions, and shared settings.
  • CRDT rooms for collaborative documents and ordered update streams.
  • Yjs sync with base64 updates, state vectors, and compaction.
  • Awareness state for editor cursors and selection details.
  • Lifecycle controls for active, idle, and destroyed rooms.
  • Snapshots for checkpointing a room or collaborative document.
  • Restore operations for returning a room to a saved state.
  • Short-lived authorization tokens for clients that need a room grant.
  • Request-aware actors so writes can automatically attach the current user.
  • Explicit actors for background jobs, imports, and service writes.
  • Instance stats for room, member, and message counts.
NeedUse
Chat, support conversations, meetings, lobbiesroom()
Deployment progress, notification streams, dashboardschannel()
Collaborative editor state, whiteboards, shared formscrdtRoom()
Yjs document synccrdtRoom().applyYjsUpdate() and crdtRoom().syncYjs()
Cursors, selections, typing state, active toolspresence() or awareness()
Close a room or delete a document streamdestroy()

Realtime has five central concepts:

  • Realtime instance: A named product module created with realtime({ name }).
  • Room: A named space with members, presence, metadata, history, snapshots, and optional CRDT state.
  • Channel: A broadcast-oriented stream with publish, broadcast, history, and stats.
  • Member: A user, client, or service that joined a room.
  • Actor: The identity associated with a write. Realtime can resolve it from request context headers or you can pass it explicitly.
Terminal window
await live.room("support_123").publish({
type: "message.created",
data: {
body: "I can help with that.",
},
idempotencyKey: "client_msg_123",
})
Terminal window
await live.channel("deployments").broadcast({
type: "deployment.finished",
data: {
deploymentId: "dep_123",
status: "success",
},
})
Terminal window
await live.room("doc_123").presence({
presence: {
cursor: 12,
selection: { from: 4, to: 12 },
},
})
Terminal window
await live.crdtRoom("doc_123").applyYjsUpdate({
updateBase64,
clientId: "browser_tab_1",
})
await live.crdtRoom("doc_123").syncYjs({
stateVectorBase64,
})
Terminal window
await live.room("temporary_room_123").destroy({
deleteHistory: true,
deleteSnapshots: true,
})

For routes with identity headers, Realtime can use the current user as the actor:

Terminal window
app.post("/rooms/:roomId/join", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const roomId = pathSegments[2]
return await live.room(roomId).join({
presence: {
status: "online",
},
})
})

You can also pass an explicit actor for service-to-service work, imports, admin actions, and background jobs.

  • Get started: Configure Realtime, publish a room message, join a room, update presence, and read history.
  • Rooms and channels: Choose rooms, channels, room metadata, publish idempotency, and channel history.
  • Presence: Track joins, presence updates, active members, leaves, and room metadata.
  • CRDT rooms: Apply document updates, use Yjs updates, publish awareness, read streams, and snapshot state.
  • Yjs: Sync Yjs updates, state vectors, awareness, and compaction.
  • History and snapshots: Write, page, snapshot, and restore room history.
  • Lifecycle: Check room state, destroy rooms, and understand WebSocket hibernation behavior.
  • Identity: Resolve actors from request context or explicit principals and issue room tokens.
  • Examples: Start with chat, support presence, collaborative documents, cleanup, deployment events, or event transport examples.
  • API reference: Review Realtime rooms, channels, history, presence, authorization, lifecycle, CRDT, Yjs, and stats operations.