localStorage vs sessionStorage
Lifetime
Section titled “Lifetime”The most important difference between the two stores is how long data lives:
localStorage
- Data persists until it is explicitly removed with
removeItemorclear, or the user clears browser data. - Closing all tabs, closing the browser, or restarting the machine does not remove the data.
- This makes it suitable for preferences, themes, or cached values that should survive sessions (e.g., dark mode toggle, saved language choice).
sessionStorage
- Data exists only for the lifetime of the browser tab (or window) in which it was created.
- As soon as that tab is closed, the data is gone — no recovery.
- Opening a new tab to the same URL starts a fresh, empty
sessionStorage. - This makes it suitable for tab-local state that should not leak across tabs (e.g., a multi-step wizard’s current step, a one-time token, a temporary form draft).
Tab and window scope
Section titled “Tab and window scope”Scope is where the two APIs differ most subtly:
// Tab A:localStorage.setItem('demo:user', 'Ada');// Tab B on the same origin sees 'Ada' immediately.
sessionStorage.setItem('demo:step', '2');// Tab B has its OWN sessionStorage — it cannot see Tab A's 'step'.There is one nuance: when a user opens a link with window.open() or Ctrl+click (which duplicates the tab), the new tab receives a copy of the parent tab’s sessionStorage at the moment it is opened. After that, the two stores are independent — changes in one do not propagate to the other.
Origin scope
Section titled “Origin scope”Both stores are scoped to the origin: scheme + hostname + port.
| URL | Origin |
|---|---|
https://example.com | https://example.com:443 |
https://app.example.com | https://app.example.com:443 (different!) |
http://example.com | http://example.com:80 (different scheme!) |
https://example.com:8080 | https://example.com:8080 (different port!) |
So https://app.example.com and https://api.example.com each have their own completely separate localStorage even though they share the same registrable domain.
Runnable: writing to both stores
Section titled “Runnable: writing to both stores”Run the snippet below to see both stores written and read back in the same page context.