By WebNest Studio Engineering Team
JavaScript Tutorial
Web Storage: localStorage and sessionStorage
Browsers give JavaScript two simple key-value storage mechanisms that persist data on the user's machine without needing a server: localStorage and sessionStorage. Both share the same API, but they differ in how long data survives.
These APIs only store strings, so storing structured data (objects, arrays) requires manual serialization with JSON.stringify() and deserialization with JSON.parse().
Why it matters
A dark-mode choice, a shopping cart or a half-written form should survive a page reload. localStorage keeps small pieces of data in the browser with a very simple API. Its two traps are that it stores only strings, and that it is never the place for anything secret.
localStorage vs sessionStorage
localStorage persists data with no expiration date — it survives page reloads, browser restarts, and even system reboots, until explicitly cleared by code or the user. sessionStorage persists only for the duration of the page session — it's cleared automatically when the tab is closed (but survives a page reload within the same tab). Both are scoped per-origin (protocol + domain + port), so one site cannot read another site's storage.
The Core API
Both objects expose the same four methods, plus a length property.
setItem(key, value)— stores a value under a key (value is coerced to a string).getItem(key)— retrieves the stored string, ornullif the key doesn't exist.removeItem(key)— deletes a single key.clear()— removes everything stored for that origin.
Storing Objects with JSON
Because storage only holds strings, storing an object directly (localStorage.setItem('user', userObj)) will store the literal text "[object Object]" instead of the data. The correct pattern is to serialize before storing and parse after reading, and to guard against missing keys or malformed JSON.
Examples
Storing and retrieving a simple string value with localStorage
localStorage.setItem('theme', 'dark');
const savedTheme = localStorage.getItem('theme');
console.log(savedTheme);
localStorage.removeItem('theme');
console.log(localStorage.getItem('theme'));
dark
null
Serializing an object to JSON before storing, and parsing it back
const user = { name: 'Asha', age: 28, roles: ['admin', 'editor'] };
localStorage.setItem('user', JSON.stringify(user));
const raw = localStorage.getItem('user');
const restoredUser = raw ? JSON.parse(raw) : null;
console.log(restoredUser.name, restoredUser.roles.join(', '));
Asha admin, editor
Common Mistakes
- Storing an object or array directly without
JSON.stringify(), resulting in the useless string "[object Object]" being saved. - Calling
JSON.parse()on a key that might not exist, which throws becausegetItem()returnednull— always check fornullbefore parsing. - Assuming localStorage is secure or encrypted — it is plain text, readable by any script running on the same origin, so it should never hold sensitive data like passwords or raw tokens.
- Confusing sessionStorage's lifetime — it survives a page reload/refresh, but not closing the tab; it is not "cleared as soon as you navigate."
Exercise
The playground preview does not allow real storage, so a stand-in object with the same getItem and setItem methods is provided; the code is identical with localStorage. Write savePrefs, which stores an object under the key prefs, and loadPrefs, which returns the stored object, or { theme: "light" } when nothing is stored.
Expected output: light, dark, string (one per line)
// Stand-in for localStorage, with the same two methods
const storage = {
data: {},
getItem(key) { return key in this.data ? this.data[key] : null; },
setItem(key, value) { this.data[key] = String(value); },
};
function savePrefs(prefs) {
// TODO: store the object as JSON under the key "prefs"
}
function loadPrefs() {
// TODO: return the stored object, or { theme: "light" } if there is none
}
console.log(loadPrefs().theme);
savePrefs({ theme: "dark" });
console.log(loadPrefs().theme);
console.log(typeof storage.getItem("prefs"));
Show hints
- Storage holds only strings, so convert with
JSON.stringifywhen saving andJSON.parsewhen loading. getItemreturnsnullfor a key that has not been set.
Show solution
// Stand-in for localStorage, with the same two methods
const storage = {
data: {},
getItem(key) { return key in this.data ? this.data[key] : null; },
setItem(key, value) { this.data[key] = String(value); },
};
function savePrefs(prefs) {
storage.setItem("prefs", JSON.stringify(prefs));
}
function loadPrefs() {
const raw = storage.getItem("prefs");
return raw ? JSON.parse(raw) : { theme: "light" };
}
console.log(loadPrefs().theme);
savePrefs({ theme: "dark" });
console.log(loadPrefs().theme);
console.log(typeof storage.getItem("prefs"));
Quick quiz
1. What type of value does localStorage store?
- A. Only strings
- B. Only numbers
- C. Any JavaScript value
- D. Only objects
Show answer
A. Other values are converted to strings, so objects must be saved as JSON.
2. What is the difference between localStorage and sessionStorage?
- A. localStorage persists until it is cleared; sessionStorage is cleared when the tab is closed
- B. sessionStorage is larger
- C. localStorage is sent to the server
- D. There is none
Show answer
A. sessionStorage is also separate for each tab.
3. What does localStorage.getItem("missing") return?
- A. undefined
- B. An empty string
- C. null
- D. It throws an error
Show answer
C. Check for null before parsing or using the value.
Interview questions
What are the differences between localStorage, sessionStorage and cookies?
Show answer
localStorage holds about 5 MB per origin, has no expiry, and is shared by all tabs of the same origin. sessionStorage has the same API but lasts only for the life of one tab. Cookies are limited to about 4 KB each, can be given an expiry, and are sent to the server with every request, which is why they are used for sessions. Cookies can also be marked HttpOnly so that JavaScript cannot read them.
Why should authentication tokens not be kept in localStorage?
Show answer
Any JavaScript running on the page can read localStorage, so a single cross-site scripting flaw, or a compromised third-party script, lets an attacker steal the token and impersonate the user. A cookie marked HttpOnly, Secure and SameSite cannot be read by scripts and is the safer place for session tokens. localStorage is for non-sensitive preferences and cached data.
Key Points to Remember
- localStorage persists indefinitely per-origin; sessionStorage is cleared when the tab closes.
- Both store only strings — use
JSON.stringify/JSON.parseto save and restore objects or arrays. - The core API is the same for both:
setItem,getItem,removeItem,clear. - Never store sensitive data in Web Storage — it is plain text and accessible to any script on the same origin.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Shows a live preview of your HTML, CSS and JavaScript. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering