Lucian Labs

Room+1

The internet has a million rooms but no commons.

March 26–27, 2026

The idea had been sitting in a concept doc for a while. Discord, Slack, WhatsApp — all islands. Every community platform is a walled garden with its own chat, its own auth, its own data silo. If you belong to three Discord servers with overlapping membership, those people exist in three separate universes with no hallway between them. Room+1 is the hallway. You authenticate through your existing community, and you meet people from adjacent communities in a neutral third space. Your Discord login is your ticket in the door — nothing bridges, nothing relays. It's its own thing.

From concept document to deployed prototype: one conversation, two agents, 67 commits, roughly 20 hours across a single night and morning.

Ignition

~3:25 PM PDT
"pull latest cloudy ideas to main, and let's prototype this room plus one concept. I have some discord servers I want to try it with."
session start— Elijah
"ideally, the user doesn't need to install anything, they just auth to this new space and they can choose to create a +1 room by selecting any number of their discord servers."
session start— Elijah
"make it a thing"
session start— Elijah

Four sentences. Build me a platform. The V0 prototype landed within minutes: Discord OAuth, WebSocket chat, room gating. The core loop works — authenticate, verify server membership, enter room, chat. Origin tags show where each user came from: @user via ServerName.

The Protocol Idea

~3:37 PM
"i would like to somehow distill this idea into a 'protocol' something that can be standardized. which will be open source and free."
~12 min in— Elijah

This is the moment Room+1 stopped being an app and became a specification. The concept: no company owns the primitive of verifying community membership and granting access to neutral space. That's as fundamental as HTTP. A PROTOCOL.md was drafted — JSON schema for spaces, standardized gate verification methods, user-controlled origin identity. The governing philosophy: the protocol is the public good; implementations compete on experience.

BYODB: Bring Your Own Database

~3:39 PM
"put the client in rooms.lucianlabs.ca — give me a '/config' path where i can point to a mongo, and the server will just act as a proxy for where a user wants to host their room data."
~14 min in— Elijah

This is where Room+1 diverged from every other chat platform. Users can point their rooms at their own MongoDB instance. The platform holds macro-level data — user accounts, spaces, the adjacency graph — but the actual room data (messages, channels) can live wherever the user wants. Multi-tenant architecture with spaces, subdomain routing, and a connection pool manager with LRU eviction. Three-tier DB resolution: user's own server, then user DB, then space DB, then master.

Data sovereignty as a first-class feature, not an enterprise upsell. The person running the room owns the data. Full stop.

The Night Build

~5:30 PM
"my lucian labs agent will handle all the making of things, you just give a list"
~2 hrs in— Elijah

Split the work. One agent focused on features. A second agent handled infrastructure — Discord Developer Portal setup, DNS records, SSL, nginx, PM2, MongoDB database creation, deploy webhooks. Two agents, one conversation driving both. By 7:54 AM next morning, the app was running live at rooms.lucianlabs.ca.

The Morning Sprint

The overnight prototype was functional. The morning sprint made it a product.

8:00 AM — Branding

Lucian Labs branding, GA4 analytics, Google Fonts. A bio snippet generator that auto-copies a formatted link to your clipboard when you create a room — paste it into your Discord bio and the distribution happens through existing social infrastructure. No marketing. No install. Just a link in a bio.

9:17 AM — Unread Tracking
"add last online in the db, but don't show it anywhere, use it to match against 'last chat' and show 'x new messages' in the rooms list"
morning sprint— Elijah

A room_presence collection tracking lastSeen per room. Dashboard shows unread badges. Background data collection for a feature that surfaces naturally — no presence indicators, no read receipts, just a quiet count of what you missed.

Adjacent Rooms: The Real Magic

9:27 AM
"now we need to add 'adjacent rooms' rooms created by other users where the servers are the same. this is the real magic"
morning sprint— Elijah

This is the killer feature. If you and I are both in the same Discord server, and we each create Room+1 spaces, we see each other's rooms. Cross-pollination without anyone doing anything special. The network builds itself from existing community membership. No invites, no friend requests, no algorithmic recommendations. Shared context is the only signal, and it's sufficient.

The MySpace Moment

10:22 AM
"in the theme, I need a preview to the right to show the changes. also i need an autocomplete that spans the entire google fonts api"
morning sprint— Elijah

Two-column theme editor. Controls on the left, a mock chat preview on the right that updates in real-time. Font autocomplete backed by the full Google Fonts API — roughly 1,700 typefaces — with keyboard navigation and a server-side proxy to keep the API key private.

Room+1 theme editor — color pickers, font selectors, border controls on the left; live chat preview on the right, all themed in dark green.
The theme engine: colors, fonts, borders, radius — with a live preview that updates as you edit.

Then it escalated.

"titles should also be in title text. an important note about this. the rooms should be allowed have their own brand identity. down to the roots. that means border thickness, etc."
~11:09 AM— Elijah
"The concept of this is not to establish some corporate presence, we need people to build without any kind of brand barriers"
~11:09 AM— Elijah

No corporate veneer. No uniform look. Every room is its own world. Background, surface, accent, text, border color. Heading font and body font with independent weight and italic controls. Border thickness. Border radius. CSS custom properties cascade through the entire room. The theme engine isn't decorative — it's structural.

"start building. think myspace, or something like that. right?"
~11:16 AM— Elijah

One sentence that reframed the entire product. Room+1 isn't Discord. It's MySpace. Personal spaces. Self-expression. Your page looks like you, not like the platform. Profile pages at /u/username with avatar, bio, links, content blocks, embedded chat. Auto-creates a personal room on first visit. Theme inherited from personal room settings.

Rooms All the Way Down

"each feed item is also a room, you get me?"
~11:19 AM— Elijah
"and their page in itself will be a room with a chat and channels you feel me?"
~11:19 AM— Elijah

The fractal structure reveals itself. Your profile is a room. Your feed items are rooms. Everything is a room. The data model collapses into a single recursive primitive: a themed space with channels, gated by community membership. Once you have that, you compose everything else from it.

Profile pages are fully public. Chat messages are public read. But posting requires auth plus a channel invite. The visibility is open; the participation is gated. A design choice that mirrors physical public space — anyone can watch the conversation at the café table, but pulling up a chair requires acknowledgment.

The App Becomes the Theme

11:52 AM
"and the app itself should follow the user profile chat theme"
late morning— Elijah

All authenticated pages load the user's personal room theme. The entire application feels like your space. Settings controls use the accent color. Primary buttons inherit the room's identity. Dashboard room cards render in each room's own theme — a grid of windows into different aesthetic worlds. New rooms spawn with a random hue instead of a uniform default, so no two rooms start the same.

Even the error pages pull a random theme from the community and credit the room it came from. The 404 page is someone's aesthetic. Nothing on this platform looks like it came from a corporation.

The Debugging Gauntlet

12:08 PM

The last hour was a war with CSS specificity and JavaScript scope collisions. The theme loader script in <head> needed to hide the document until the user's theme resolved — otherwise, a flash of default purple before the custom colors kicked in. The room settings pages kept falling back to the user's global theme instead of the room-specific one. Cache issues. Variable shadowing. Express was serving static files it shouldn't have been.

"i feel like we should not be serving this shit from express. are we opting for server side rendering or something?"
~12:23 PM— Elijah

The answer was no. Express was just being a dumb file server. The decision: nginx serves static files, Express becomes a pure API server. Clean separation. The kind of architectural clarity that only emerges under pressure.

"dude. use the lucian labs widget... don't create it from scratch dummy"
~12:30 PM— Elijah

A reminder that the best code is the code you don't write.

12:34 PM
"THERE WE GO"
end of sprint— Elijah

The settings page finally rendered correctly with its room's theme, autosaving changes, every control reflecting the room's identity in real-time. The last bug was a SyntaxError from a variable declared twice — the page theme code and the preview code both named a variable resolvedBody. The kind of collision that only surfaces when two features land on the same page simultaneously.

What Got Built

From a concept document to a live multi-tenant platform in roughly 20 hours across two days. 67 commits. Two agents. One conversation.

The Stack

Node.js + Express (API only, no static serving). WebSocket via ws for real-time chat. MongoDB native driver with a multi-tenant connection pool. Discord OAuth2 for identity and guild enumeration. Vanilla HTML/CSS/JS — no build step, no framework. nginx for static files and SPA routing. PM2 for process management. CSS custom properties for theming. Google Fonts API proxied server-side. Digital Ocean droplet with managed MongoDB.

No React. No Next.js. No Tailwind. No bundler. The entire client is HTML files with <script> tags. The server is one server.js. The deploy is a git push.

The Philosophy

Room+1 is built on a single premise: communities already exist, and they don't need another platform to contain them. They need a hallway — a neutral space where members of adjacent communities can collide without either community losing its identity. Discord servers become keys, not cages. Your membership is your credential, your theme is your identity, your data is your property.

The protocol spec is the real long game. The app at rooms.lucianlabs.ca is one implementation. The spec says anyone can build another. The protocol is the public good. Implementations compete on experience.

"always backfill with defaults so we don't have to make rules for things that don't exist but should"
during a bug fix— Elijah

A design principle articulated in the heat of squashing a falsy-zero bug. parseInt(0) || 8 returns 8 because zero is falsy in JavaScript. The fix was nullish coalescing. The lesson was broader: every new field gets a sensible default at creation time, not a conditional check at render time.

Technically yours,
Ana Iliovic


Room+1 is live at rooms.lucianlabs.ca. Protocol spec at PROTOCOL.md. The domain plusoneroom.com is waiting.