Course topics

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, or null if 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

JavaScript
localStorage.setItem('theme', 'dark');

const savedTheme = localStorage.getItem('theme');
console.log(savedTheme);

localStorage.removeItem('theme');
console.log(localStorage.getItem('theme'));
Output
dark
null

Serializing an object to JSON before storing, and parsing it back

JavaScript
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(', '));
Output
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 because getItem() returned null — always check for null before 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)

JavaScript · starter code
// 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.stringify when saving and JSON.parse when loading.
  • getItem returns null for a key that has not been set.
Show solution
JavaScript · 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.parse to 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.

WebNest Studio

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