Open-source Durable Objects for live applications.
Build chat rooms, presence, collaborative cursors, multiplayer sessions, live dashboards, notifications, and user-scoped queues without assembling Redis, WebSockets, sticky sessions, workers, locks, and tables by hand.
durable-objects
realtime
websocket
stateful-runtime
live-apps
nodejs
zero-dependencies
Nalo is a single-node runtime for building realtime features with addressed stateful objects.
Nalo gives every live thing in your app a stable address and a small stateful runtime:
object = compute + durable storage + realtime channel
Use it for AI sessions and other live objects where one address should own state, connected clients, and event ordering.
- One address per live entity:
ws://host/ws/<type>/<id> - One object owns state, connected clients, and event ordering
- No external dependencies for the v0.1 runtime
- Browser demos included: cursors, chat, todo, counter
- CLI generator for a self-contained app
- Tests cover HTTP, WebSocket fanout, persistence, CLI output, and packaging
From this repo:
npm startAs a package:
npm install nalo-runtime
npx nalo demonpm startOpen:
http://127.0.0.1:8787/
Best first demo:
http://127.0.0.1:8787/room.html
Open it in two tabs. You get live cursors, presence, chat, and persistent room state backed by one object.
Regenerate the README demo GIF:
npm run demo:gifRequires ffmpeg on your machine.
import { NaloObject } from "./lib/runtime.js";
export class Room extends NaloObject {
async onConnect(socket) {
socket.sendJSON({ type: "state", state: await this.state() });
}
async onMessage(socket, message) {
const messages = await this.storage.get("messages", []);
messages.push(message);
await this.storage.put("messages", messages);
this.broadcast({ type: "message", message });
}
async state() {
return {
messages: await this.storage.get("messages", [])
};
}
}Register it:
runtime.register("room", Room);Then connect to an addressed object:
WS /ws/room/lobby
GET /o/room/lobby
npm start
npm run doctor
node ./bin/nalo.js create my-app/room.html collaborative cursors + presence + chat
/counter.html durable counter broadcast to every tab
/chat.html persistent chat room
/todo.html shared todo list
npm test
npm pack --dry-runThe integration tests open a temporary local HTTP/WebSocket port.
Most realtime apps are secretly stateful. The hard part is not sending a WebSocket frame. The hard part is deciding who owns state, where concurrent events are serialized, how reconnects get current state, and how many services you need before the feature is reliable.
Nalo explores one primitive:
/ws/<type>/<id>
Route everything for that live entity to one durable object. Let the object own the state and the connected clients.
Nalo v0.1 is a finished single-node runtime:
- single Node process
- no external dependencies
- JSON file persistence with atomic writes
- in-memory storage adapter for tests/embedded use
- HTTP object API
- WebSocket fanout
- lifecycle hooks:
onConnect,onMessage,onDisconnect - demo objects and browser demos
- CLI app generator
- TypeScript declarations
It is not a distributed cloud runtime yet. The next product line is distribution: object placement, replication, production storage backends, auth, and managed hosting.
