Search selfstore
v1.8.21

Your side project does not need a backend (yet)

An honest decision tree for when a web app actually needs a server - and how far durability, backups and multi-device sync go without one.

Here is the moment every side project dies a little: the app works, people like it, and now you “just” need accounts, a database, hosting, backups, monitoring, a privacy policy and a plan for the 3 a.m. page. The feature was a notes app. The estimate is now a company.

This article is the decision tree I wish someone had handed me, with the honest boundaries marked.

What a backend actually buys you

Strip away habit, and servers earn their keep for exactly four things:

  1. Durability: the data survives the user’s device.
  2. Multi-device: the same data on the laptop and the phone.
  3. Multi-user: data shared between different people.
  4. Secrets and authority: things the client must not hold (API keys, payment logic, anti-cheat, moderation).

Numbers 3 and 4 genuinely need infrastructure. If your app is one person’s data, though, you are probably building a backend for numbers 1 and 2, and those two stopped requiring one.

What the browser gives you for free

Modern browsers are serious runtimes: IndexedDB stores gigabytes of structured data, WebCrypto does real AES-GCM and key derivation, BroadcastChannel and Web Locks coordinate tabs, and the File System Access API writes actual files to disk. A progressive web app installs to the home screen and runs offline.

What the platform does not give you is the loop that turns those primitives into trustworthy persistence: a file format, encryption done right, conflict-free convergence between devices, and the discipline to survive “clear site data”. That gap is why people default to servers, and it is a library-shaped gap, not an infrastructure-shaped one.

Durability without a server

The trick is to separate the working copy from the durable home. The working copy lives in IndexedDB and absorbs every keystroke. The durable home is storage the user already owns: a file on disk, their Google Drive, their Nextcloud, an S3 bucket. The app writes an encrypted backup there on every change.

Cleared browser? Stolen laptop? Reattach the home, everything is back. And because the home receives ciphertext (AES-256-GCM, key derived from the user’s password with Argon2id), the storage provider learns nothing. Google holds bytes it cannot read.

Note what happened to your GDPR surface: there is none. You cannot leak what you never receive.

Multi-device without a sync server

The durable home doubles as a rendezvous. Each device pushes its encrypted backup and folds in what the others pushed; a hybrid logical clock and per-collection merge strategies make convergence deterministic, and conflicting concurrent edits are journaled with both values instead of silently dropped. The “sync server” is a file on a Drive. It has no uptime, no bill and no breach surface.

This is the part selfstore packages: the format, the crypto, the merge and the lifecycle, behind two functions you write (gather() and apply()). The quick start is genuinely five minutes.

When you do need the server

Draw the line honestly, it will save you a rewrite:

The pitch, minus the romance

Start local-first. Ship the app as static files, keep the data on the device, back it up to the user’s own storage, sync through it. You inherit offline, privacy and zero hosting cost on day one, and your users inherit ownership of their data as real files with a documented format.

If the project later grows a genuine server-shaped need, add the server for that need, not for storage reflexes. The notes app stays a notes app; the company can wait until there is something to incorporate for.


Try selfstore in five minutes, or read the other notes.