Vibes DIY
Vibes DIY / Blog
From the build log

Your app is a database you can npm install

Here's a party trick that's actually an architecture: take any vibe you own — say a guestbook app running at vibes.diy/vibe/you/guestbook — and run this on your laptop:

jsimport { fireproof } from "use-vibes";

const db = fireproof("messages", { appSlug: "guestbook" });

await db.put({ text: "hello from Node", at: Date.now() });

db.subscribe((changes) => {
  console.log("someone wrote from the browser:", changes);
}, true);

That's the whole program. The put shows up in every open browser tab of the app, live. A visitor tapping a button in the app lands in your script's subscribe a beat later. Same database, two peers, both directions — no REST endpoint to design, no schema to migrate, no glue service in the middle.

Branded title card: “npm i ⇄ live db” over a duotone photo of a patch-cabled synthesizer.
Patch a new cable into a running system. The music doesn't stop.

The mental model: a resident app and visiting peers

The way to think about it: your deployed vibe is the resident — the always-on peer that owns the data and serves every browser. Your script is a transient peer that drops in, does its job, and leaves. Cron job that summarizes the day's entries? Transient peer. Importer that backfills three years of CSV? Transient peer. A long-running monitor that watches for a particular document and fires off an email? A transient peer that happens to stay a while.

Get posts like this in your inbox

One email field. Real updates. No algorithm required.

There's exactly one rule that makes the connection work: use the same bare database name your App.jsx uses. The server routes on the triple (owner handle, app slug, database name) — nothing gets prefixed or namespaced on your behalf. If the app says fireproof("messages"), your script says fireproof("messages", { appSlug: "guestbook" }) and you're in the same room.

No keys to leak

The part that usually makes "connect a script to prod" annoying is credentials. Here it's one command: npx vibes-diy login enrolls the device with a certificate, and every script on that machine authenticates as you — request-signing under the hood, no API key to mint, copy into an env var, commit by accident, and rotate in a panic. Your access function sees your handle on every write, exactly as if you'd tapped the button in the browser. Which also means the permissions story requires zero new thought: the script can do whatever you can do in the app, and nothing more.

Two footguns, disarmed

We built a proof-of-concept against a real deployed vibe to make sure the docs tell the truth, and it surfaced exactly two stumbles worth naming:

  • The option is userHandle, not userSlug. If you're connecting to an app under a different handle than your default, pass userHandle: "alice". The wrong key isn't an error — it's silently ignored, and you'll wonder why you're staring at an empty database.
  • subscribe hands you changed _ids, not full documents. It's a doorbell, not a delivery. Re-read with db.get(id) to materialize the doc before acting on it.

Everything else behaves the way the browser API does, because it is the browser API — the same use-vibes package your generated app imports.

If you've been treating your vibe as "just a frontend," this is the door out: the full setup, the API table, and worked Node/Workers examples are in the Connect Backend Data guide. And if what you want is code running inside the platform — cron, webhooks, on-write triggers — that's backend.js, which speaks to the same database from the other side.

Your data, from anywhere JS runs

Build the app in a prompt, then script against its live database from Node, Deno, Bun, or a Worker.

Start building →

Enjoyed this? Get the next post by email

One email field. Real updates. No algorithm required.

Prefer a feed? RSS · Atom