localStorage vs sessionStorage: A Complete Comparison
Web Storage API provides two mechanisms for storing data in the browser: localStorage and sessionStorage. Both store key-value pairs, but they have important differences. Let's explore when and how to use each.
Overview
| Feature | localStorage | sessionStorage |
|---------|--------------|----------------|
| Persistence | Until manually cleared | Until tab/window closes |
| Scope | Shared across tabs | Per tab/window |
| Storage Limit | ~5-10 MB | ~5-10 MB |
| Server Access | No (client-side only) | No (client-side only) |
localStorage
Data persists until explicitly deleted — even after closing the browser.
Basic Usage
// Store data
localStorage.setItem('username', 'john_doe');
localStorage.setItem('theme', 'dark');// Retrieve data
const username = localStorage.getItem('username');
console.log(username); // 'john_doe'
// Remove specific item
localStorage.removeItem('theme');
// Clear all data
localStorage.clear();
// Check how many items stored
console.log(localStorage.length);
// Get key by index
console.log(localStorage.key(0));
Storing Objects
localStorage only stores strings, so you need to serialize objects:
// Store object
const user = {
name: 'John',
email: 'john@example.com',
preferences: {
theme: 'dark',
notifications: true
}
};localStorage.setItem('user', JSON.stringify(user));
// Retrieve object
const storedUser = JSON.parse(localStorage.getItem('user'));
console.log(storedUser.name); // 'John'
Use Cases for localStorage
- User preferences — Theme, language, layout settings
- Authentication tokens — Remember logged-in users
- Shopping cart — Persist items between sessions
- Form data — Auto-save drafts
- App state — Remember user's last position
sessionStorage
Data persists only for the current browser tab/window session.
Basic Usage
// Same API as localStorage
sessionStorage.setItem('currentStep', '3');
const step = sessionStorage.getItem('currentStep');
sessionStorage.removeItem('currentStep');
sessionStorage.clear();
Key Differences from localStorage
- Tab-specific: Each tab has its own sessionStorage
- Cleared on close: Data is deleted when the tab closes
- Not shared: Opening a new tab doesn't share the data
Use Cases for sessionStorage
- Multi-step forms — Track progress in a wizard
- Temporary state — Data that shouldn't persist
- One-time operations — Prevent duplicate submissions
- Per-session data — Shopping cart that resets each visit
Practical Examples
Theme Persistence with localStorage
// Get saved theme or default to 'light'
function getTheme() {
return localStorage.getItem('theme') || 'light';
}// Save theme preference
function setTheme(theme) {
localStorage.setItem('theme', theme);
document.body.className = theme;
}
// Apply saved theme on page load
document.addEventListener('DOMContentLoaded', () => {
setTheme(getTheme());
});
// Toggle theme
document.getElementById('themeToggle').addEventListener('click', () => {
const current = getTheme();
setTheme(current === 'light' ? 'dark' : 'light');
});
Form Auto-Save with sessionStorage
const form = document.getElementById('myForm');
const textarea = document.getElementById('content');// Restore saved content
textarea.value = sessionStorage.getItem('draft') || '';
// Save on input
textarea.addEventListener('input', () => {
sessionStorage.setItem('draft', textarea.value);
});
// Clear on submit
form.addEventListener('submit', () => {
sessionStorage.removeItem('draft');
});
Shopping Cart with localStorage
const cart = {
items: [], load() {
const saved = localStorage.getItem('cart');
this.items = saved ? JSON.parse(saved) : [];
return this.items;
},
save() {
localStorage.setItem('cart', JSON.stringify(this.items));
},
add(product) {
const existing = this.items.find(item => item.id === product.id);
if (existing) {
existing.quantity++;
} else {
this.items.push({ ...product, quantity: 1 });
}
this.save();
},
remove(productId) {
this.items = this.items.filter(item => item.id !== productId);
this.save();
},
clear() {
this.items = [];
localStorage.removeItem('cart');
},
getTotal() {
return this.items.reduce((sum, item) =>
sum + (item.price * item.quantity), 0
);
}
};
// Initialize cart
cart.load();
Storage Events
Listen for storage changes across tabs:
window.addEventListener('storage', (event) => {
console.log('Key:', event.key);
console.log('Old Value:', event.oldValue);
console.log('New Value:', event.newValue);
console.log('URL:', event.url); // React to changes
if (event.key === 'theme') {
document.body.className = event.newValue;
}
});
Note: This event only fires in OTHER tabs/windows, not the one that made the change.
Best Practices
1. Check for Support
function storageAvailable(type) {
try {
const storage = window[type];
const x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch (e) {
return false;
}
}if (storageAvailable('localStorage')) {
// Use localStorage
}
2. Handle Quota Exceeded
function safeSetItem(key, value) {
try {
localStorage.setItem(key, value);
return true;
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.error('Storage full!');
// Handle: clear old data, warn user, etc.
}
return false;
}
}
3. Use Namespacing
Prefix keys to avoid conflicts:
const APP_PREFIX = 'myApp_';function setAppData(key, value) {
localStorage.setItem(APP_PREFIX + key, JSON.stringify(value));
}
function getAppData(key) {
const value = localStorage.getItem(APP_PREFIX + key);
return value ? JSON.parse(value) : null;
}
4. Don't Store Sensitive Data
Web Storage is not secure:
- Accessible via JavaScript (vulnerable to XSS)
- Not encrypted
- Visible in DevTools
Never store:
- Passwords
- Credit card numbers
- Personal identification numbers
ProLiveEditor Uses localStorage!
ProLiveEditor saves your code using localStorage. That's why your HTML, CSS, and JS persist even after closing your browser! Try it:
// See ProLiveEditor's stored code
console.log(localStorage.getItem('pro-html'));
console.log(localStorage.getItem('pro-css'));
console.log(localStorage.getItem('pro-js'));
Understanding web storage helps you build better, more user-friendly applications. Practice these concepts in ProLiveEditor!