Browser Storage
Persisting data in the browser — localStorage, sessionStorage, IndexedDB, cookies, and Cache API.
JSON.stringify turns a Date into a string, and JSON.parse leaves it as a string. So a date saved to localStorage, even through a careful wrapper, comes back as text like "2026-10-18T…Z". The first call to .getTime() or .getFullYear() on it throws, and that's often in code far from where the date was saved.
localStorage.setItem("lastVisit", JSON.stringify(new Date()));
const lastVisit = JSON.parse(localStorage.getItem("lastVisit"));
console.log(typeof lastVisit);
console.log(lastVisit.getTime());
// string
// TypeError: lastVisit.getTime is not a functionSaving data in the browser
By default, JavaScript variables disappear when the page refreshes. Browser storage APIs let you save data that persists — across refreshes, across sessions, and even offline.
localStorage — the most common choice
// Store a string:
localStorage.setItem("city", "Mumbai");
// Retrieve it:
console.log(localStorage.getItem("city")); // "Mumbai"
// Missing key returns null (not undefined):
console.log(localStorage.getItem("missing")); // null
// Remove one item:
localStorage.removeItem("city");
// Clear everything:
localStorage.clear();
// ─ KEY LIMITATION: everything is a string ─
// Objects must be JSON-encoded:
const user = { name: "Alice", score: 95 };
localStorage.setItem("user", JSON.stringify(user)); // store
const loaded = JSON.parse(localStorage.getItem("user")); // retrieve
console.log(loaded.name); // "Alice"JSON.stringify when storing and JSON.parse when reading.
Forgetting this is the most common localStorage mistake.
sessionStorage — same API, tab-only
// Same API as localStorage, but data is cleared when the tab closes:
sessionStorage.setItem("step", "2"); // wizard step
console.log(sessionStorage.getItem("step")); // "2"
// Use sessionStorage for:
// - Multi-step form data (gone if they close the tab — intentional)
// - Temporary UI state that shouldn't persist
// - Per-tab settingsA safe storage wrapper
// Wrap localStorage to handle JSON automatically and errors gracefully:
const store = {
get(key, fallback = null) {
try {
const item = localStorage.getItem(key);
return item !== null ? JSON.parse(item) : fallback;
} catch {
return fallback;
}
},
set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
return true;
} catch (e) {
// QuotaExceededError — storage is full
console.warn("Storage full:", e.message);
return false;
}
},
remove(key) { localStorage.removeItem(key); },
clear() { localStorage.clear(); },
};
// Usage:
store.set("settings", { theme: "dark", fontSize: 16 });
const { theme } = store.get("settings", { theme: "light" });
console.log(theme); // "dark"The store wrapper above has the same limit: it handles JSON-friendly values (strings, numbers, booleans, plain objects and arrays), and everything else comes back changed. For dates, save a timestamp, which is a plain number, and rebuild the Date when you read it:
localStorage.setItem("lastVisit", JSON.stringify(Date.now())); // a timestamp is a plain number
const lastVisit = new Date(JSON.parse(localStorage.getItem("lastVisit"))); // turn it back into a Date
console.log(lastVisit instanceof Date);
console.log(lastVisit.getFullYear());
// true
// 2026Cookies vs localStorage
Official Sources
- MDN Web Docs — Web Storage API
- MDN Web Docs — IndexedDB API
- MDN Web Docs — Cache
- MDN Web Docs — Using cookies
- idb — IndexedDB wrapper library
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.