videoskilletdecisions Open the app ↗

0005 — Saved profiles live in Firestore, and need an account

Status: accepted, 2026-08-07; partly superseded by 0010.

Context#

The app grew a saved-profile library: name the board, get it back later. The first version kept it in localStorage, beside Scenes and the pinned-slider list, because that is where every other durable thing in this app lives and it needed no backend.

That store is the wrong shape for the one thing a saved profile promises. A profile is worth naming because you want it later — and "later" is usually a different machine, a different browser, or after the day someone clears site data. localStorage cannot promise any of those. It is per-origin, per-browser, and it is the first thing a cleanup wipes. The library was the one feature in the app whose value grew the longer it survived, stored in the one place that guarantees it will not.

The replacement is Firebase Authentication (Google) plus Cloud Firestore, project ntscjs-d4f56, one document per user at users/{uid}.

Decision#

Firestore is the only store for profiles, and saving requires being signed in. There is no local copy and no offline queue: signed out, the save box is replaced by a sign-in button, ctrl+S refuses out loud (the button goes amber and reads sign in), and the ⌘K row says why. (Since 2026-09-16 the library button reads saved in every state, and the account sits in a control beside it, so the refusal still turns that button amber under a label that no longer changes. Splitting them was a legibility fix, and it leaves this decision as it is.)

The alternative — local-first with the cloud as a mirror — was considered and declined. It is friendlier in the moment and it is what ytshuffle2 does, but it buys that friendliness with a merge: the same name saved on two devices, a profile deleted on one and still present on the other, edits made signed out that have to survive a later sign-in. ytshuffle2 shows the failure mode — its adoptCloudData assigns the cloud library over the local one, so anything saved while signed out is lost at the next sign-in, silently. One store has one truth and needs no reconciliation, and a library that quietly loses entries is worse than one that says "sign in first".

What this does not touch. Everything else in the app works exactly as it did, signed out, offline, forever: presets, the 1–9 scenes, pinned sliders, the URL that carries the whole look, the ⧉ link beside each saved profile. An account buys the library and nothing else, and no feature was moved behind it. (0010 widens that last sentence: the account also carries the session last open and a still per profile, so a signed-in visitor can pick a setup back up. No feature moved behind the account to do it.)

Consequences#