Phase 3 · Browser DevelopmentModule 20~36 min read

Browser Storage & State

Persist browser-side state with Web Storage and IndexedDB while respecting privacy and limits.

What you'll learn

Browser storage persists state across interactions and visits, but each option has different capacity, query, lifetime, privacy, and security properties.

By the end of this lesson, you'll be able to:

  • Choose Web Storage or IndexedDB
  • Version serialized state
  • Avoid persisting secrets

Core mental model

Use this decision table as a compact reference. Focus on what each tool means and when it earns its place in production code.

ConceptWhat it meansDecision rule
localStorageSynchronous string storage for an originUse only for small, non-sensitive preferences
sessionStorageString storage scoped to one tab sessionUse for disposable per-tab state
IndexedDBAsync transactional object databaseUse for substantial structured or offline data

Professional workflow

Build the behavior in small, observable steps. Each step should leave something you can inspect or test.

  1. Describe the client storage boundary: inputs, outputs, state, timing, and expected failures.
  2. Implement the smallest correct path with names that expose intent.
  3. Add edge cases and failure handling before introducing abstractions.
  4. Verify behavior with realistic data and one deliberately adversarial example.
  5. Refactor only after the observable behavior is protected.

Make behavior observable

Before optimizing or abstracting, make inputs, outputs, state changes, timing, and failure paths visible. JavaScript becomes much easier to reason about when hidden work is exposed.

Guided code lab

Persist a versioned preference

Versioning gives future code a migration decision instead of blindly trusting old data.

preferences.js
const key = "course-preferences";
const preferences = { version: 1, theme: "dark", compact: false };
localStorage.setItem(key, JSON.stringify(preferences));
const saved = JSON.parse(localStorage.getItem(key) ?? "null");
console.log(saved?.version === 1 ? saved.theme : "default");

Recover from corrupted storage

Stored state is external input and must be parsed defensively.

safe-storage.js
function readJson(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    return raw === null ? fallback : JSON.parse(raw);
  } catch {
    localStorage.removeItem(key);
    return fallback;
  }
}

Production practice

Contract

Keep the client storage API explicit: accepted state, emitted events, DOM ownership, and cleanup.

Verification

Test with keyboard input, missing elements, repeated initialization, and teardown—not only a mouse happy path.

Operations

Measure user-visible latency and remove listeners, observers, object URLs, or media tracks when the feature ends.

Common failure mode

Tokens, passwords, personal records, and other secrets do not belong in Web Storage because same-origin scripts can read them.

Independent workshop

Add durable preferences and recoverable draft state to a lesson-notes feature.

Your finished workshop must include:

  • Namespaced versioned keys
  • Corruption fallback
  • A documented retention and privacy policy

Definition of done

Demonstrate the happy path and at least two edge cases, keep responsibilities separated, and add a short note explaining one design choice.

Recap & quick check

Key takeaways

  • Web Storage is synchronous and string-only
  • IndexedDB is async and structured
  • Stored data needs validation and versioning
  • Do not store secrets casually

Quick check

1. What type does localStorage return?

2. Which API fits large structured offline data?

3. Is stored JSON trusted input?

Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.