Lesson 0001 · ~10 minutes

When IndexedDB fits (and when it doesn’t)

One skill: place IndexedDB on the client storage spectrum and pick it only when the hard problem is durable structured app data in the browser.

Win for this lesson

After the quiz, you can defend “IndexedDB yes / no” in a design review without writing a line of indexedDB.open yet.

1. The problem IndexedDB solves

Network can be slow, flaky, or offline. Even when it’s fine, re-fetching large structured data on every visit wastes time and bandwidth. Users also expect drafts, settings, and “last known good” UI state to survive a refresh.

IndexedDB is the browser’s main answer for large-scale structured data kept on the client: objects (and more), looked up by keys, with transactions, indexes, and room to grow far past the old ~5 MB string stores. web.dev puts it bluntly in its recommendation: for most non-file, non-HTTP-asset data, use IndexedDB.

It is asynchronous (does not force a main-thread freeze the way localStorage can), origin-scoped, and available from windows, workers, and service workers — which is why it pairs well with the Workers track you already finished.

2. Not “a little SQL in the browser”

People say “database” and picture tables + SQL. IndexedDB is different:

MDN’s basic concepts guide is the short normative mental model for that shape.

3. The client storage spectrum

Ordered by “what job is this store built for?” — not by coolness. Steal the map from Storage for the web.

Memory only

React/Vue state, module variables. Fastest. Dies on refresh. Fine when re-fetch or re-derive is cheap.

sessionStorage

Tab-scoped string map; survives reloads in that tab, not other tabs. Sync API; tiny; not for workers. Prefer sparingly.

localStorage

Origin-scoped string map that persists. Sync on main thread; ~few MB; no workers. Avoid for bulk or hot-path structured data.

Cookies

Tiny values often sent on every HTTP request. Session/auth use-cases only — not a general client database.

IndexedDB

Large structured app data: drafts, entity caches, offline queues, user-generated records. Async; keys + indexes; works off-main-thread.

Cache API

Request/Response pairs — HTML/JS/CSS/images and other HTTP resources for load/offline shells. Wrong default for arbitrary JSON entities.

OPFS

File-shaped bytes on an origin-private filesystem. Editors, media pipelines, “this is a file” models — not the first stop for keyed records.

Default rule (steal this)

If the hard part is “persist structured application data on this device so we can show or edit it without a round trip”, start with IndexedDB. If the hard part is “make the app shell and static assets load offline”, that is the Cache API (usually with a service worker) — different job. If the hard part is “tiny flag that can be a string” and you accept sync main-thread cost, Web Storage may be enough. If the hard part is “truth lives on the server and re-fetch is fine”, prefer no durable client store.

Signal Leans IndexedDB Leans away
Shape Objects, lists, drafts, entity caches, queues HTTP assets, pure files, tiny string flags
Size / access Larger than a few MB; need keys/indexes One boolean; or only Request/Response caching
Threading Want async; maybe workers writing/reading OK to block main thread for a trivial string
Lifetime Survive refresh; offline-capable UX Ephemeral UI; server always authoritative + online-only
Classic fits Offline note drafts, mail/message cache, cart, form autosave, large filterable lists Theme toggle string, auth cookie, offline app.js shell, video file editor buffer
FE integration difficulty (honest preview)

Opening a store is not the hard part. What bites teams later: schema version upgrades (migrations while old tabs are open), transaction lifetimes (async gaps abort work), quota / eviction (especially Safari policies), and pretending client data is automatically multi-device truth. We’ll drill those later. Today only know they exist so you don’t oversell “just use IndexedDB.”

4. Practice — pick the store

Choose the best default. Equal-length options so formatting doesn’t hint. Feedback is immediate.

Scenario A

Writing app: multi-paragraph drafts must survive refresh and work offline until the user hits Publish.

Scenario B

PWA shell: HTML, CSS, and JS must load so the UI appears when the network is completely gone.

Scenario C

Settings: remember light/dark theme across visits. One string; slightly delayed apply is fine.

Scenario D

CRM: cache ~50k contact objects offline for search and detail views; a worker may pre-index in the background.

Scenario E

Internal admin: always online; table of 20 rows from REST; no offline requirement; refresh is acceptable.

5. What to remember

Ask your teacher Anything fuzzy — “what about Redux Persist?”, a feature on your team, Safari quirks you already hit — ask in chat. Follow-up questions are part of the method, not a distraction.

Primary source (read next)

web.dev — Storage for the web (Pete LePage et al.). Best short primary for this lesson’s spectrum and defaults. Then skim MDN’s basic concepts behind IndexedDB so the next lesson’s API vocabulary isn’t new twice.