If you've ever struggled with javascript local storage vs session storage, you're not alone. In this hands-on tutorial, I'll walk you through everything from the basics to real-world applications — with code you can actually use in your projects.
Understanding Web Storage
The Web Storage API gives you two mechanisms for storing key-value pairs in the browser: localStorage and sessionStorage. They share the same API but differ in how long data persists.
// Both use the same API:
localStorage.setItem('key', 'value');
sessionStorage.setItem('key', 'value');
// Get values
const local = localStorage.getItem('key'); // 'value'
const session = sessionStorage.getItem('key'); // 'value'
// Remove specific item
localStorage.removeItem('key');
// Clear everything
localStorage.clear();
Key Differences
| Feature | localStorage | sessionStorage |
|---|---|---|
| Lifespan | Until manually cleared | Until tab is closed |
| Shared across tabs? | Yes (same origin) | No (per tab) |
| Size limit | ~5-10 MB | ~5 MB |
| Use case | User preferences, themes | Form drafts, temp state |
Storing Complex Data
Web Storage only stores strings. For objects and arrays, use JSON:
// Store an object
const user = { name: 'Alice', theme: 'dark', lang: 'en' };
localStorage.setItem('user', JSON.stringify(user));
// Retrieve and parse
const stored = JSON.parse(localStorage.getItem('user'));
console.log(stored.name); // 'Alice'
// Store an array
const recentSearches = ['python tutorial', 'js closures', 'css grid'];
localStorage.setItem('searches', JSON.stringify(recentSearches));
// Helper functions for cleaner code
const storage = {
get(key, fallback = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : fallback;
} catch {
return fallback;
}
},
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
remove(key) {
localStorage.removeItem(key);
}
};
// Usage
storage.set('settings', { volume: 80, quality: 'high' });
const settings = storage.get('settings', { volume: 50 });
Real-World Examples
Dark Mode Toggle with localStorage
// Check saved preference on page load
const theme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', theme);
// Toggle function
function toggleDarkMode() {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
}
// Attach to button
document.getElementById('theme-toggle').addEventListener('click', toggleDarkMode);
Form Auto-Save with sessionStorage
// Auto-save form data as user types
const form = document.getElementById('contact-form');
const fields = ['name', 'email', 'message'];
// Restore saved data
fields.forEach(field => {
const saved = sessionStorage.getItem(`form_${field}`);
if (saved) document.getElementById(field).value = saved;
});
// Save on input
fields.forEach(field => {
document.getElementById(field).addEventListener('input', (e) => {
sessionStorage.setItem(`form_${field}`, e.target.value);
});
});
// Clear on submit
form.addEventListener('submit', () => {
fields.forEach(field => sessionStorage.removeItem(`form_${field}`));
});
Storage Events and Cross-Tab Communication
When localStorage changes in one tab, other tabs of the same origin receive a storage event:
// Tab A: Update a value
localStorage.setItem('notification', JSON.stringify({
message: 'New order received!',
timestamp: Date.now()
}));
// Tab B: Listen for changes
window.addEventListener('storage', (event) => {
if (event.key === 'notification') {
const data = JSON.parse(event.newValue);
showNotification(data.message);
}
console.log('Changed:', event.key);
console.log('Old value:', event.oldValue);
console.log('New value:', event.newValue);
});
storage event only fires in other tabs, not the one that made the change. Use this for cross-tab sync like logout notifications.Best Practices and Security
- Never store sensitive data (passwords, tokens, PII) in Web Storage — it's accessible via JavaScript and vulnerable to XSS
- Always use try/catch — storage can be full or disabled in private browsing
- Set size limits — check available space before storing large data
- Use sessionStorage for temporary state — form drafts, wizard progress
- Use localStorage for preferences — theme, language, display settings
// Safe storage wrapper with size checking
function safeSetItem(key, value) {
try {
const serialized = JSON.stringify(value);
// Check approximate size (2 bytes per char in UTF-16)
const sizeKB = (serialized.length * 2) / 1024;
if (sizeKB > 4096) {
console.warn(`Storage item "${key}" is ${sizeKB.toFixed(0)}KB — consider alternatives`);
}
localStorage.setItem(key, serialized);
return true;
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.error('Storage quota exceeded!');
// Optionally clear old data
}
return false;
}
}
Full-Stack Developer & Technical Writer at DRIXO
Full-stack developer with 5+ years of experience in Python and JavaScript. I love breaking down complex concepts into simple, practical tutorials. When I'm not coding, you'll find me contributing to open-source projects.
Comments