Local Storage and Session Storage for Simple Data
· 4 min read
Everything we've stored so far — variables, objects, arrays — disappears the moment the page is closed or reloaded. loc
Everything we've stored so far — variables, objects, arrays — disappears the moment the page is closed or reloaded. localStorage and sessionStorage are simple, browser-provided ways to keep small bits of data around between visits, without needing a server or a database at all.
LocalStorage Vs SessionStorage
Both work identically in terms of the API; the only difference is lifespan. localStorage persists until explicitly cleared — it survives closing the tab, closing the browser, even restarting the computer. sessionStorage is wiped the moment the tab is closed, and is scoped to that one tab only (even a page open in a second tab from the same site gets its own separate sessionStorage).
localStorage.setItem("username", "Vikesh Singh");
const name = localStorage.getItem("username");
console.log(name);
localStorage.removeItem("username");
console.log(localStorage.getItem("username"));
setItem(key, value) stores a value under a key, getItem(key) retrieves it, and removeItem(key) deletes it. After removeItem, getItem returns null, since the key no longer exists — same null-handling habits from the DOM lesson apply here.
Storing Objects And Arrays As JSON
There is exactly one real catch that trips up almost every beginner the first time: localStorage only stores strings. Trying to store an object or array directly silently converts it to the useless string "[object Object]".
const user = { name: "Tony Stark", alias: "Iron Man" };
localStorage.setItem("user", user);
console.log(localStorage.getItem("user"));
localStorage.setItem("user", JSON.stringify(user));
const stored = localStorage.getItem("user");
console.log(stored);
const parsedUser = JSON.parse(stored);
console.log(parsedUser.name);
The first attempt stores and then retrieves the literal string "[object Object]" — completely useless, and no error is thrown to warn you, which is exactly why this mistake is so common. The fix is the same JSON.stringify/JSON.parse pairing from the fetch and error-handling lessons: stringify the object before storing it, and parse the retrieved string back into a real object before using it.
A Practical Example: Dark Mode
A practical, realistic use case: remembering a user's preference, like a dark-mode toggle, across visits.
function setDarkMode(enabled) {
localStorage.setItem("darkMode", JSON.stringify(enabled));
document.body.classList.toggle("dark", enabled);
}
function loadDarkModePreference() {
const saved = localStorage.getItem("darkMode");
const enabled = saved ? JSON.parse(saved) : false;
document.body.classList.toggle("dark", enabled);
}
loadDarkModePreference();
Notice saved ? JSON.parse(saved) : false — this is a ternary operator, a compact if/else in one line (condition ? valueIfTrue : valueIfFalse). It's needed here because on a brand-new visitor's first load, localStorage.getItem("darkMode") returns null, and JSON.parse(null) would actually return null rather than throwing, which could cause subtle bugs downstream — so we explicitly default to false when nothing was saved yet.
A small but genuinely useful trick: storing a whole list and updating it.
function addToCart(item) {
const cart = JSON.parse(localStorage.getItem("cart")) || [];
cart.push(item);
localStorage.setItem("cart", JSON.stringify(cart));
}
addToCart({ name: "JavaScript Course", price: 0 });
addToCart({ name: "CSS Course", price: 0 });
console.log(JSON.parse(localStorage.getItem("cart")));
JSON.parse(localStorage.getItem("cart")) || [] reads the stored cart, and falls back to a fresh empty array if nothing was stored yet (since null is falsy, the || kicks in — this is the same truthy/falsy mechanic from lesson 9). Every call to addToCart reads the current list, modifies it, and saves the whole thing back — localStorage has no concept of "append one item," only full replacement of a key's value.
Security Limitations Of LocalStorage
An important limitation worth knowing honestly: localStorage is not secure storage. Anything stored there is plain text, readable by anyone with access to the browser's developer tools, and it's accessible to any JavaScript running on that page — including, if your site has an XSS vulnerability from the innerHTML risk mentioned in the DOM lesson, malicious injected code. Never store passwords, tokens meant to stay secret, or sensitive personal data in localStorage.
It's also worth knowing the storage event, which fires automatically on other tabs (not the tab that made the change) whenever localStorage is modified. This lets two open tabs of the same site stay in sync — for example, logging out in one tab can notify another open tab to also clear its session. window.addEventListener("storage", function(event) { console.log(event.key, event.newValue); }) is how you'd listen for it. It's a fairly specialized feature, but worth recognizing by name if you ever see multiple tabs of the same app needing to react to each other's changes.
A final practical habit: before storing anything in localStorage, ask how large it might realistically grow. Browsers cap localStorage at a few megabytes per site (the exact limit varies by browser), which is plenty for settings, small lists, or simple notes, but the wrong tool for anything resembling a real database of growing records — that's a strong signal you actually need a backend server, which the fetch lesson's POST example points toward.
A small challenge: build a tiny "notes" feature that stores an array of text notes in localStorage, with a function to add a note and a function to list all current notes, using the JSON.stringify/JSON.parse pattern throughout. Reload the page afterward and confirm your notes are still there — that persistence across a reload is the entire point of this lesson.
KEEP READING