Skip to content

Getting started

This guide adds Realtime to a Layeron backend, creates a room, publishes messages, tracks presence, and reads history.

Import realtime from @layeron/modules. Create a named instance and register it with app.use(...).

Terminal window
import { backend } from "@layeron/core"
import { realtime } from "@layeron/modules"
const app = backend()
const live = realtime({
name: "live",
historyLimit: 100,
presenceTtlSeconds: 60,
})
app.use(live)

name is the stable instance name. Use one instance for the main live surface of an app, or multiple instances with the platform namespace model for different products or tenants.

Terminal window
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 message = await request.json()
const result = await room.publish({
type: "message.created",
data: message,
})
return Response.json(result, { status: 201 })
})

type is the event name your client will handle. data is JSON payload for the event.

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

When the route is authenticated, Realtime can attach the current user as the actor. Use memberId when a client or device needs a stable room-specific member key.

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

Presence is useful for online state, cursors, selections, typing indicators, and temporary client state.

Terminal window
app.get("/rooms/:roomId/history", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const roomId = pathSegments[2]
const history = await live.room(roomId).history({
limit: 50,
})
return Response.json(history)
})

Use cursor from the previous result to page through older messages.

  • 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: Store collaborative document updates, awareness, streams, and snapshots.
  • Yjs: Sync Yjs updates, state vectors, awareness, and compaction.
  • History and snapshots: Write, page, snapshot, and restore room history.
  • Identity: Resolve actors from request context or explicit principals and issue room tokens.