Migration Guides
From a custom IndexedDB implementation
If your app already has a hand-rolled IndexedDB layer — a getDb/getCached/setCached trio, maybe some manual TTL logic — this page covers what that code is usually missing by the time it's a year old: Safari eviction recovery, LRU eviction, cross-tab write coordination, and per-user scoping, and how each maps onto a Flux registration.
Prerequisites
- An existing hand-rolled IndexedDB caching layer — object stores, manual TTL envelopes, or similar
- A state manager Flux can write into — Zustand, Redux, or Jotai — see state-managers/zustand
- Familiarity with api/register on the client side
1
The pattern, not the specific code
Something close to this exists in a lot of production codebases — usually written once during a "make this feel instant" push, then patched for years afterward.
typescript
2
What this tends to cost over time
Roughly the order teams discover each of these, based on how a hand-rolled IDB layer usually ages in production.
typescript
3
get/set boilerplate → registration
The connection-promise ceremony and manual staleness math both disappear — registration is a declaration, not a function you call and await on every read.
typescript
4
Safari eviction recovery → built in
This one is usually discovered in production, not development, and the fix is easy to get subtly wrong by hand.
typescript
5
Manual eviction → byte-budget LRU
"Add eviction" tends to become its own multi-day project. Here it's four lines of configuration.
typescript
6
Cross-tab write races → mirrored writes
The bug that's hardest to reproduce on demand and easiest to dismiss as a fluke the first few times it's reported.
typescript
7
Retrofitted per-user isolation → scope
Retrofitting user-boundary isolation onto keys that were never namespaced for it means touching every call site — and a missed one is a data leak, not just a bug.
typescript
Self-healing even if clearUserSession() is skipped
A boot-time sweep catches sessions that never call this at all — a crashed tab, a closed laptop lid — see core-concepts/multi-tenant-scoping.
8
What doesn't move
Not every use of IndexedDB is a "cache with TTL" problem — keep these as-is rather than forcing them through a registration for consistency's sake.
typescript
9
Migrating without a big-bang cutover
Flux's engine uses its own namespaced database, so the old and new caching layers can run side by side with zero collision during migration.
typescript
For the full IDB engine internals referenced throughout this page, see core-concepts/idb-ttl. For the offline queue this page doesn't cover, see core-concepts/offline-queue. For the multi-tenant isolation model in Step 7, see core-concepts/multi-tenant-scoping.