Question

localStorage, sessionStorage, Sessions, and Cookies in JavaScript

htmlcookieslocal-storagesession-storage

Question

What are the technical advantages and disadvantages of localStorage, sessionStorage, server-side sessions, and cookies? When should each option be used in a web application?

Short Answer

You will learn where browser storage and server-side sessions keep data, how long that data lasts, whether it is sent with HTTP requests, and which choice fits common tasks such as preferences, temporary form state, and authentication.

Concept

localStorage, sessionStorage, cookies, and server-side sessions all help an application remember information. However, they store that information in different places and have different security and lifetime rules.

  • localStorage is browser storage that persists after the browser is closed. JavaScript can read and write it.
  • sessionStorage is browser storage that lasts only for one browser tab's page session. JavaScript can read and write it.
  • Cookies are small browser values that can be automatically included in HTTP requests to a matching server.
  • A server-side session stores data on the server. The browser usually holds only a session identifier, commonly in a cookie.

This distinction matters because a value stored in the browser is exposed to JavaScript running on the page. A server-side session can keep sensitive application state off the device, while a protected cookie tells the server which session belongs to the visitor.

A common authentication design is:

  1. The server creates a session after a successful sign-in.
  2. The server stores user-related session data in a database, cache, or memory store.
  3. The browser receives a cookie containing an opaque session ID.
  4. On later requests, the browser sends that cookie and the server looks up the session.

The word session can be confusing: sessionStorage is a browser Web Storage API, while a server-side session is an application feature managed by a backend.

Mental Model

Think of the browser as a backpack and the server as a secure office.

  • localStorage is a labeled pocket in the backpack that remains there until someone empties it.
  • sessionStorage is a temporary pocket used for one open notebook (one tab). Close that notebook, and the pocket is emptied.
  • A cookie is a small return label attached to every relevant letter sent to the office.
  • A server session is a file stored in the office. The return label contains only a file number, so the office can find the correct file.

For non-sensitive preferences, a backpack pocket can be convenient. For login state, it is usually safer to keep the important information in the office and use a protected return label.

Take Quiz

Syntax and Examples

Browser Web Storage uses string keys and string values.

// localStorage: survives browser restarts until removed
localStorage.setItem("theme", "dark");
const theme = localStorage.getItem("theme"); // "dark"
localStorage.removeItem("theme");

// sessionStorage: available only in this tab's page session
sessionStorage.setItem("checkoutStep", "2");
const step = sessionStorage.getItem("checkoutStep"); // "2"
sessionStorage.clear();

To store an object, convert it to JSON when saving and parse it when reading:

const preferences = { theme: "dark", fontSize: 18 };

localStorage.setItem("preferences", JSON.stringify(preferences));

const saved = localStorage.getItem("preferences");
const restoredPreferences = saved ? JSON.parse(saved) : null;

Cookies can be created in browser JavaScript only when they are not HttpOnly:

document.cookie = "language=en; Max-Age=2592000; Path=/; SameSite=Lax";

In production, a server commonly sets an authentication cookie because it can add important flags:

Set-Cookie: sessionId=opaque-random-id; HttpOnly; Secure; SameSite=Lax; Path=/
  • HttpOnly prevents page JavaScript from reading the cookie.
  • Secure sends it only over HTTPS.
  • SameSite helps control when browsers send it in cross-site contexts.
  • Path=/ makes it available throughout the site.

JavaScript cannot directly create a HttpOnly cookie; only an HTTP response from the server can do that.

Step by Step Execution

Consider saving a visitor's theme preference:

const savedTheme = localStorage.getItem("theme");
const theme = savedTheme ?? "light";

document.body.dataset.theme = theme;

function setTheme(nextTheme) {
  document.body.dataset.theme = nextTheme;
  localStorage.setItem("theme", nextTheme);
}

setTheme("dark");

Execution trace:

  1. getItem("theme") looks for a value saved under the theme key. It returns a string or null.
  2. ?? "light" chooses the saved value when it exists; otherwise it uses "light".
  3. document.body.dataset.theme updates the page so CSS can apply the selected theme.
  4. setTheme("dark") updates the page immediately.
  5. setItem("theme", "dark") saves the choice for future visits.
  6. If the user closes and reopens the browser later, localStorage can still contain "dark", provided the user or browser has not cleared site data.

If this used sessionStorage instead, the preference would normally disappear when that tab's page session ends.

Real World Use Cases

  • localStorage: theme choice, dismissed announcement state, recently viewed item IDs, or a non-sensitive draft that should survive a restart.
  • sessionStorage: current multi-step form state, a one-tab search workflow, or a temporary redirect return path.
  • Cookies: language preference that the server needs while rendering a page, consent state, or a session identifier.
  • Server-side sessions: authenticated user identity, authorization state, shopping-cart state, password-reset workflow state, and temporary server-controlled data.

Choose based on who needs the data:

  • If only browser JavaScript needs non-sensitive data, Web Storage is often suitable.
  • If the server must receive a small value automatically with requests, a cookie may fit.
  • If data is sensitive, trusted, or too large for a cookie, keep it in a server-side session or database.
Take Quiz

Real Codebase Usage

In real projects, storage decisions are usually wrapped in small helper functions rather than scattered throughout UI code.

function loadJson(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    return raw === null ? fallback : JSON.parse(raw);
  } catch {
    return fallback;
  }
}

function saveJson(key, value) {
  localStorage.setItem(key, JSON.stringify(value));
}

Common patterns include:

  • Validation and fallback values: Treat missing, malformed, or old stored data as normal. Use a safe default.
  • Namespaced keys: Use keys such as myapp:theme and myapp:cart to avoid confusion between features.
  • Server-set authentication cookies: Backends set HttpOnly, Secure, and appropriate SameSite attributes. Frontend code does not need to read the session ID.
  • Session lookup middleware: The backend reads the session ID cookie, loads the server session, and attaches the authenticated user to the request.
  • Logout invalidation: Remove or invalidate the server session and clear the session cookie. Do not merely hide the user interface.
  • Minimal cookie data: Since cookies are sent with relevant requests, avoid putting large or frequently changing application state in them.

Common Mistakes

Storing secrets in localStorage

// Risky: any JavaScript that runs on this origin can read it.
localStorage.setItem("accessToken", token);

An XSS vulnerability can let an attacker-controlled script read Web Storage. Do not store passwords, private keys, or other secrets there. For cookie-based authentication, a server-set HttpOnly cookie reduces exposure to JavaScript, but XSS is still dangerous and must be prevented.

Forgetting that Web Storage stores strings

localStorage.setItem("isAdmin", false);

if (localStorage.getItem("isAdmin")) {
  // Runs because the stored value is the non-empty string "false".
}

Use JSON parsing or compare explicitly:

const isAdmin = JSON.parse(localStorage.getItem("isAdmin") ?? "false");

Calling JSON.parse on a missing value

const settings = JSON.parse(localStorage.getItem("settings"));

If no value exists, getItem returns null, and parsing can fail. Check first or provide a fallback.

Treating sessionStorage as shared browser-wide storage

sessionStorage is scoped to an origin and a particular top-level browsing context. Another tab normally has its own separate value.

Putting large data in cookies

Cookies are small, commonly limited to roughly 4 KB per cookie, and are sent on matching requests. Large cookies waste bandwidth and may exceed browser or server limits.

Trusting client-side values for authorization

Never use a browser value such as localStorage.getItem("role") as proof that someone is an administrator. The server must verify permissions using trusted server-side data.

Comparisons

FeaturelocalStoragesessionStorageCookieServer-side session
Primary locationBrowserBrowserBrowserServer
Typical lifetimeUntil clearedUntil tab page session endsSession or configured expiryServer-defined expiry
Sent automatically with requestsNoNoYes, when cookie rules matchNo; the session ID cookie usually is
Readable by page JavaScriptYesYesUsually yes, unless HttpOnlyNo
Suitable for sensitive dataUsually noUsually noSession ID can be protected with flagsYes, with proper server security
Typical capacityLarger than cookies; browser-dependentLarger than cookies; browser-dependentSmall, often about 4 KB per cookieDepends on server storage
Tab behaviorShared by same-origin tabsSeparate per tab/page sessionShared according to cookie scopeShared when requests use the same session ID

localStorage vs sessionStorage

Use localStorage when non-sensitive data should remain available after closing the browser. Use sessionStorage when the data should be temporary and isolated to one tab.

Cookie vs server-side session

A cookie is a browser storage and transport mechanism. A server-side session is data stored by the backend. They are often used together: the cookie carries an ID, and the backend uses that ID to find session data.

Take Quiz

Cheat Sheet

  • localStorage.setItem(key, value) saves a string persistently.
  • localStorage.getItem(key) returns a string or null.
  • sessionStorage has the same API but is limited to one tab's page session.
  • Use JSON.stringify(value) before saving objects or arrays.
  • Use JSON.parse(value) only after handling missing or invalid data.
  • Web Storage is same-origin and readable by JavaScript on that origin.
  • Avoid storing passwords, private keys, and sensitive tokens in Web Storage.
  • Cookies are small and can be sent automatically with matching requests.
  • Prefer server-set auth cookies with HttpOnly, Secure, and an appropriate SameSite value.
  • A server-side session keeps the actual session data on the backend; the browser generally stores only an opaque session ID.
  • Never trust browser storage for authorization decisions.

FAQ

Is localStorage safer than cookies?

Not automatically. localStorage is readable by JavaScript, so XSS can expose its contents. A cookie with HttpOnly cannot be read by page JavaScript, but cookie-based authentication needs CSRF protections and appropriate SameSite settings.

Does localStorage expire automatically?

No standard expiry is built into localStorage. It remains until application code, the user, or the browser clears it. Store an expiry timestamp yourself if needed.

Does sessionStorage clear when I refresh the page?

Normally, no. It generally survives reloads within the same tab's page session, but it is removed when that session ends, such as when the tab is closed.

Can a server read localStorage?

No. localStorage is not automatically included in HTTP requests. Client JavaScript would have to read it and explicitly send a value in a request.

Why are cookies used for login sessions?

Browsers automatically send matching cookies with requests. A server can set a protected HttpOnly session-ID cookie and look up the real session data on the server.

Can I store an object directly in localStorage?

No. Web Storage stores strings. Serialize objects with JSON.stringify and restore them with JSON.parse.

Should I store a user's role in a cookie or localStorage?

You may store it for display convenience, but never trust it for security. The server must check the user's real permissions for every protected operation.

Take Quiz

Mini Project

Description

Build a small preference manager for a website. It saves a theme permanently, keeps a temporary checkout step only for the current tab, and safely restores stored JSON data. This demonstrates the appropriate use of localStorage and sessionStorage without using them for authentication secrets.

Goal

Create a page that remembers a theme across visits and tracks a checkout step only until the current tab is closed.

Requirements

Use localStorage to save either a light or dark theme.

Take Quiz

Keep learning

Related questions

View more