A lightweight real-time event bus built with Deno and Fresh, with a browser workspace for collaborative chat, file sharing, and room-level dashboard actions.
- Realtime room channels over WebSockets
- Built-in apps in one workspace:
- Chat
- File sharing (up to 512 KB per file)
- Shared dashboard (online count, message/file counters, shared note)
- Raw event feed
- In-memory room history with persisted event types
- Polished UI with custom Tailwind theme tokens plus handcrafted CSS
- Runtime: Deno
- HTTP layer: Fresh (
@fresh/core) - Transport: native WebSockets (
Deno.upgradeWebSocket) - Frontend: Fresh-rendered shell + Preact hooks app (
src/frontend/client.js) with colocated styles (src/frontend/styles.css) - Theme customization: Tailwind CDN config + component layer embedded in the Fresh-rendered page
Requirements: Deno >= 1.40
deno task startDevelopment mode with file watching:
deno task devType check:
deno task checkServer defaults:
- UI:
/ - WebSocket endpoint:
/ws - Port:
8000(override withPORT)
Client handshake:
{ "type": "hello", "name": "Ava", "room": "ops" }Server ready payload:
{
"type": "ready",
"channel": "room:ops",
"session": { "id": "...", "name": "Ava", "color": "#22d3ee", "room": "ops" },
"users": [{ "id": "...", "name": "Kai", "color": "#4ade80" }],
"history": [
{ "type": "event", "action": "chat.message", "data": { "text": "hi" } }
]
}Publish payload:
{
"type": "publish",
"channel": "room:ops",
"action": "chat.message",
"data": { "text": "Deploying build #214" }
}Persisted actions:
chat.messagefiles.sharedashboard.counter.bumpdashboard.note.set
Ephemeral actions:
chat.typing.startchat.typing.stoppresence.joinpresence.leavepresence.state
- State is in-memory only; restarting the server clears channels and history.
- The single-page workspace is rendered by Fresh from
src/server.ts, then hydrated into a Preact component app fromsrc/frontend/client.js.