Vibes DIY
Vibes DIY / Docs
Data guide

Local-first data and sync

Your app's local store is its database. Reads and writes do not need to wait for a round trip to the server: writes always succeed locally, and sync runs in the background.

NETWORK Your device first-party · vibes.diy origin vibes.diy server authoritative · background Local store + sync engine THE DATABASE An IndexedDB replica on the top page — reads & writes hit it directly, no round-trip. this is the database Vibe app (iframe) RENDERER useFireproof() crosses a postMessage bridge to the local store — not the network. access.js SERVER-ONLY Runs only here, on ingest. Decides who may read & write — the client can’t bypass it. Other devices’ replicas Accepted changes stream to everyone whose access still matches. 1 put() instant · optimistic 2 sync 3 accept reject Accept fans the change out to other replicas. Reject overwrites your optimistic copy, server-wins — silently — your code never catches it. If the rule gave a reason, the platform shows it.

Revocation stops the feed — it doesn’t reach back

When access is removed, the server stops routing new data to that device. Changes already synced there stay on it — “stops receiving,” not remote-erase.

local · instant server · authoritative accept · fan out reject · server-wins
Where your app’s data lives, and how a write travels: applied locally and instantly, synced in the background, decided by access.js on the server, then fanned out or converged server-wins.

Offline means sync is not caught up

When a device is offline, people can keep reading and changing data already on that device. Those changes wait locally. When connectivity returns, sync catches up and replicas converge.

A successful local write does not mean the server has accepted it yet. Access rules still run only on the server. If the server refuses a signed-in write, the server's authorized version silently replaces the local version. Conflicts are resolved last-write-wins for the whole document; individual fields are not merged independently.

Signed-out visitors are the one exception. A write the server doesn't accept merely because the visitor has no identity yet is not replaced — it is saved locally as a pending change and syncs automatically when that visitor signs in. Only a write the server's access rules actually refuse converges back to server truth.

This silent server-wins behavior is deliberate. A possible someday-enterprise log mode could preserve rejected writes for an administrator's audit trail, but that mode is only an idea and is not part of today's creator contract.

Access controls sync, not copies already delivered

The server evaluates your access function and syncs only the channels its outputs authorize. Apps and clients do not evaluate access functions or grant themselves channels.

Revoking access stops that person receiving your data from then on. It does not remotely erase records already synced to their device. The same rule applies to social controls:

  • removing a follower or being unfollowed stops future follower-only data;
  • blocking stops future data delivery through that relationship;
  • neither action promises to erase copies the other person already received.

An honest client may evict records after access changes, but eviction is local storage hygiene, not a security boundary. Design sharing flows with the same rule you would use for a downloaded file: only share data that the recipient may retain.

For channel and role rules, see the Access API. For app-level roles, invitations, and controls, see Sharing & Access.