You've come a long way, baby
A year ago, if you asked where the Vibes DIY backend was, the honest answer was: there wasn't one. The product was a React Router v7 single-page app backed by Netlify functions, and the entire "server side" was a key-vending machine — an endpoint that provisioned an OpenRouter key into your browser so the client could call the model itself. Today a vibe is a synced multiplayer database, an access policy, a server that can think, and an app you edit from inside itself, all riding one WebSocket stream. This is the story of the distance between those two sentences — and of the engineer who did the hardest, least visible part of the work.
The app with no backend
You can date the starting point precisely, because our agent documentation remembers it. The first CLAUDE.md lands in June 2025 and describes the whole product in a breath: a React Router v7 SPA, Netlify functions, a useSimpleChat hook, Fireproof documents for chat messages. Two commands: pnpm dev and pnpm check.
The architecture was radical in its absence. When you generated an app, your browser talked to the model directly — the call-ai library made HTTP calls to OpenRouter from the client. The one piece of infrastructure we ran was the key plumbing: a small key-management module fetched you a metered OpenRouter key from vibecode.garden, stashed it in the browser, and refreshed it when it ran dry. Your data never left the tab unless Fireproof synced it. Generation, data, auth: all client-side.
Let's be fair to that design, because it was the right first move. It shipped in weeks. It had nearly zero operational surface — no database to migrate, no server to page anyone about. It was local-first by default, which is still in our DNA. A two-person project got a real product into real hands on an architecture a weekend could hold.
And let's be honest about what it couldn't do. API keys lived in browsers, which is a sentence that ends every security review early. There was no server-side truth — nothing to share, nothing to enforce, nothing to meter. Every feature we now consider the product — live multiplayer data, per-app access rules, a server side — was not merely unbuilt; it was unbuildable. There was nowhere to put anything that needed to outlive a tab.
Enter Meno Abels
Getting from there to here required someone to do the least glamorous work in software: rebuild the foundation while the house stays occupied. That someone was Meno Abels, and this section is the kudos he's owed.
Meno came to the project with the kind of pedigree you want for exactly this job — including a stint at Vercel helping make that platform world-ready: the practice of taking a platform that works and making it work everywhere, for everyone, under load. He's since moved on from the project. The architecture didn't move on with him; it's the floor everything since stands on.
Get posts like this in your inbox
One email field. Real updates. No algorithm required.
The shape of his contribution is preserved in the project's own history notes, which inventory what landed with the jchris/go-live integration. Read as a list, it's the anatomy of a platform:
- The monolithic chat handler became split, typed API packages —
api-impl,api-svc,api-types,api-sql— services and protocol types instead of one file that did everything. - The prompt-chat-section protocol — the literal "stream" in this post's headline. A WebSocket-driven chat protocol with explicit modes (
chat,img,fs-set,fs-update), aPromptStylesystem, and a rules-bag abstraction that replaced scattered conditionals across prompt assembly. Every generation you've watched stream into a card since then has ridden this protocol. - A real SQL layer — schemas and migrations under Drizzle, ending the raw-SQL era.
- The runtime split and sandbox import maps — vibe code imports
call-aianduse-fireproofby name, but the specifiers are import-map aliases rendered server-side per request. This seam is why we could later swap the entire client library story without touching a single deployed vibe. - Test infrastructure — isolated per-test databases, SQLite/Postgres flavor switching. Hold that thought; it matters again two sections from now.
- Deploy tag families — the prod/canary/package tag conventions we still ship with daily.
- Session-token and device-ID CA scaffolding — the auth groundwork that our later in-house identity work built on.
Notice what's not on that list: features. Nothing here was something a user saw the week it merged. All of it is load-bearing for everything a user has seen since. That's the signature of platform work done right, and it's why it so rarely gets a blog post of its own.
Here's the tell that it was foundational: Meno is gone, and his name is still in the load-bearing places. The integration branch was mabels/vibes-diy-api; our branching conventions were written around his streams. You stop noticing plumbing exactly when it's good.
A prototype becomes a platform the day someone makes it boring underneath. Meno made us boring underneath. Thank you, Meno.
What the stream unlocked
Once every generation, every deployed vibe, and every builder session rode one WebSocket protocol, the platform grew the way a coral reef grows on a shipwreck — fast, and in every direction at once. The last ninety days alone produced twelve headline features: Firefly live data, access.js per-app access rules, backend.js, in-place generation that deleted the preview pane, a first paint measured like a product metric, server-rendered vibes, env vars and secrets, a real CLI.
But one feature closes the loop on this story better than any other. We began as the platform that provisioned an OpenRouter key into your browser. Today, when a vibe's server side needs to think, it calls ctx.callAI — and no key exists anywhere in your app. The platform places the call like a switchboard operator, meters it to the user who triggered it, and hands your code the answer. We went from key-vending machine to no-keys-at-all. The thing we used to be is now the thing we specifically engineered out of existence.
And we're not sentimental about the old world. The vibecode.garden key endpoint is gone. The HTTP call-ai path is on a deliberate deprecation ladder. The direction is embed-first: one runtime, many hosts, the stream protocol becoming something you can point at any page.
The other transition: agents wrote most of this
The platform transition had a twin, and they fed each other. In the SPA era, the code was human-typed with an assistant watching. Today, about 95% of the pull requests that build this platform are agent-authored — a shift with its own documentation trail, from the growth of one CLAUDE.md into forty runbooks to the working culture we extracted into a portable skill.
Here's the connection people miss, and the reason this post gives Meno the middle third: his architecture is what made agentic development tractable here. Agents working in parallel need hard walls — typed package seams so a change stays inside its blast radius, a rules-bag instead of scattered conditionals so behavior lives in one place, per-test database isolation so a hundred concurrent test runs don't fight, deploy tags so shipping is a convention rather than a conversation. Meno built those walls before we knew we'd need them for this. The 270-PRs-in-17-days velocity isn't recklessness; it's what a well-partitioned architecture permits.
There's a pleasing irony to close on: the product itself deliberately refuses to be an agent loop. The generator is a pure function — database state in, one streamed response out. A pure function, built by loops.
A long way, with receipts
"You've come a long way, baby" is usually a story reconstructed from memory. This one never had to be: the first CLAUDE.md, the key-vending code, the integration branch, the merge inventory — the project kept its receipts the whole way, and this blog has been publishing the story as it happened. If you want to see what all that plumbing buys you as a builder, the creator documentation is the map.
The road keeps going — embed-first is next, and the stream protocol wants to run everywhere. But mile markers matter. From a browser holding an API key to a platform holding the stream, in about a year, without stopping the product to do it.
The stream runs through everything we ship, and it runs on Meno's architecture. Thanks, Meno. You made it boring underneath — which is the highest compliment infrastructure gets.
See how far you can get in an afternoon
The platform that took a year to build makes apps in a minute. Describe one and watch it stream in.
Start building →