localStorage
localStorage is an object provided by the browser for storing key and value pairs in persistent client side storage. It is the simplest way to keep small pieces of data right in the user's browser so that they survive a page reload.
Theory
TL;DR
- Data in
localStorageis not deleted when the page reloads. - It is available within one origin (the same-origin rule).
- It is kept even after the browser is closed, until it is cleared manually.
- The storage holds strings only, objects must be serialized with
JSON. - Methods:
setItem,getItem,removeItem,clear,key, plus thelengthproperty. - The quota is usually 5-10 MB, and sensitive data must not be stored there.
- A change made in another tab of the same origin fires a
storageevent.
Quick example
// Save a value
localStorage.setItem('username', 'Tim');
// Read a value
console.log(localStorage.getItem('username')); // "Tim"
// Remove a single value
localStorage.removeItem('username');
// Clear the whole storage
localStorage.clear();How data is stored
localStorage keeps everything as strings:
localStorage.setItem('count', 10);
console.log(typeof localStorage.getItem('count')); // "string"To store objects you need JSON.stringify() and JSON.parse():
const user = { name: 'Tim', age: 25 };
localStorage.setItem('user', JSON.stringify(user));
const savedUser = JSON.parse(localStorage.getItem('user'));
console.log(savedUser.name); // "Tim"The main methods
| Method | What it does | Example |
|---|---|---|
setItem(key, value) | Stores a value | localStorage.setItem('theme', 'dark') |
getItem(key) | Reads a value | localStorage.getItem('theme') |
removeItem(key) | Removes an entry | localStorage.removeItem('theme') |
clear() | Wipes the storage completely | localStorage.clear() |
key(index) | Returns the key at an index | localStorage.key(0) |
length | Number of entries in the storage | localStorage.length |
When a key is missing, getItem() returns null, not undefined, and that matters for your checks.
Example: remembering the site theme
const toggle = document.querySelector('#toggle');
// On page load
if (localStorage.getItem('theme') === 'dark') {
document.body.classList.add('dark');
}
// On click
toggle.addEventListener('click', () => {
document.body.classList.toggle('dark');
const theme = document.body.classList.contains('dark') ? 'dark' : 'light';
localStorage.setItem('theme', theme);
});Now the browser remembers the chosen theme, and on the next visit the user sees the same mode.
The difference from sessionStorage
| Storage | Lives until... | Available after a reload | Shared between tabs |
|---|---|---|---|
localStorage | The user clears it | Yes | Yes (within one origin) |
sessionStorage | The tab is closed | No | No |
Limits, security and the storage event
- The
localStoragequota is limited, usually 5-10 MB per origin. - It works with text data only.
- Passwords, tokens and sensitive information must not be stored in plain form: any script on the page, including a third party one, can read them.
- Data is available only within the same origin, under the same-origin rule.
- The API is synchronous, so a large
JSON.parse()on startup blocks the main thread.
If you open a site in two tabs and change localStorage in one, the other receives a storage event:
window.addEventListener('storage', (event) => {
console.log('localStorage change:', event.key, event.newValue);
});The event does not fire in the tab where the change happened, only in the others.
Summary
| What it does | Example |
|---|---|
| Stores data locally | localStorage.setItem('key', 'value') |
| Is not cleared on reload | Yes |
| Reachable from any JS on the same origin | Yes |
| Stores strings only | Use JSON.stringify() |
| Security | Do not store sensitive data |
| Size | About 5 MB |
In short: localStorage is a "mini database" in the browser where you can keep settings, history or application state and read them back even after the tab is closed.
Common mistakes
- Putting an object into the storage directly.
localStorage.setItem('user', user)stores the string"[object Object]", you needJSON.stringify(). - Forgetting that everything comes back as a string.
localStorage.getItem('count') + 1gives"101", not11, the number must be coerced withNumber(). - Calling
JSON.parse()withouttry/catch. A corrupted or foreign value throws and breaks page startup. - Storing access tokens. Any XSS on the page takes them instantly, an httpOnly cookie is the better place for a session.
- Not handling the quota. When the storage is full or site data is disabled in the browser,
setItem()throws aQuotaExceededError. - Confusing
nullwithundefined. A missing key yieldsnull, so a=== undefinedcheck never matches. - Using
clear()instead ofremoveItem().clear()wipes the data of the whole origin, including entries written by another part of the application.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.