FrontendPro

91Implement browser storage with TTL and schema-version migration

mediumAbout 40 minutesCodingstoragemigrationscaching

Problem

Apps that store data in localStorage eventually change the shape of that data, and stale entries pile up forever. Implement createStorage({ namespace, version, migrations = {}, storage = window.localStorage, now = Date.now }):

  • set(key, value, { ttl } = {}) stores an envelope { v: version, value, expiresAt } as JSON under "{namespace}:{key}". ttl is in milliseconds; without it, the entry never expires. Returns true on success, false if storage is full even after evicting expired entries.
  • get(key) returns the value, or undefined if it is missing, expired (then delete it) or unreadable (corrupt JSON: delete it).
  • If a stored envelope has an older v, run the migrations in order (migrations[2](value) upgrades v1 to v2, migrations[3] v2 to v3…), save the migrated value, and return it. If its v is newer than version (written by a newer deploy), treat it as missing and delete it.
  • remove(key) deletes one entry; clear() deletes only this namespace's keys.
const prefs = createStorage({
  namespace: "prefs",
  version: 2,
  migrations: { 2: (v1) => ({ theme: v1.darkMode ? "dark" : "light" }) },
});
prefs.set("ui", { theme: "dark" });
prefs.set("draft", text, { ttl: 24 * 60 * 60 * 1000 });

Try it yourself

Write your solution, run it, then submit to check it against the tests.

App.jsxReact + DOM

Step-by-step

{ v, value, expiresAt } stores the schema version and the expiry next to the data, so each entry can be checked independently.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever