Frontend Labs
⋯

44. localStorage and sessionStorage: API, quotas, pitfalls

Both are part of the Web Storage API, sharing the same simple key-value string interface, and are NOT sent with HTTP requests (unlike cookies) — purely client-side, only ever read by JS explicitly.

localStorage.setItem("theme", "dark");     // persists across tabs, browser restarts, forever
localStorage.getItem("theme");             // "dark"
localStorage.removeItem("theme");
localStorage.clear();                       // wipes EVERYTHING for this origin

sessionStorage.setItem("draft", "hello");  // scoped to ONE TAB, cleared when that tab closes
                                             // (a NEW tab to the same site, even same URL,
                                             // gets a fresh, empty sessionStorage)

Real gotchas engineers hit repeatedly:

  • Synchronous, main-thread blocking: every getItem/setItem call is synchronous disk I/O on the main thread — storing large values or calling it in a hot loop measurably janks the page. There is no async Web Storage API; if you need async, that's a signal to use IndexedDB (§45) instead.
  • Strings only: setItem silently coerces non-strings via String(value) — storing an object without JSON.stringify first stores the useless literal string "[object Object]".
  • ~5-10MB quota per origin (varies by browser), and exceeding it throws a QuotaExceededError you must catch explicitly.
  • Not available in all contexts: throws in some sandboxed iframes and in Safari's Private Browsing mode (historically silently no-oped, now throws) — always wrap in try/catch for a library meant to run broadly.
  • Never store secrets in plaintext: any XSS on the page can read localStorage directly — see §47 for what this specifically does and doesn't rule out.
function safeSetItem(key, value) {
  try {
    localStorage.setItem(key, JSON.stringify(value));
    return true;
  } catch (err) {
    if (err.name === "QuotaExceededError") console.warn("Storage full");
    return false;
  }
}

Generated from real-life-JS-guide.md · 8 Oct 2026 16:36