Local Storage is an HTML5 feature that allows you to store data in the user's browser with no expiration date. The data persists even after the browser is closed and reopened, making it perfect for saving user preferences, form data, and application state.
What is Local Storage?
Local Storage is part of the Web Storage API, which provides a simple way to store key-value pairs in the browser. Unlike cookies, the data in Local Storage:
- Never expires (unless manually deleted)
- Is not sent to the server with every HTTP request
- Has a larger storage capacity (typically 5-10MB per domain)
- Is easier to work with using JavaScript
- Only accessible from the same origin (domain, protocol, and port)
Basic Operations
Local Storage provides a simple API with four main methods:
Storing Data
// Store a value
localStorage.setItem('username', 'JohnDoe');
localStorage.setItem('theme', 'dark');
localStorage.setItem('fontSize', '16');
// Alternative syntax (less recommended)
localStorage.username = 'JohnDoe';
localStorage['theme'] = 'dark';Retrieving Data
// Get a value
const username = localStorage.getItem('username');
console.log(username); // "JohnDoe"
const theme = localStorage.getItem('theme');
console.log(theme); // "dark"
// Returns null if key doesn't exist
const email = localStorage.getItem('email');
console.log(email); // null
// Alternative syntax
const fontSize = localStorage.fontSize;Removing Data
// Remove a specific item
localStorage.removeItem('username');
// Clear all items
localStorage.clear();Checking if Key Exists
// Check if a key exists
if (localStorage.getItem('theme') !== null) {
console.log('Theme is set');
}
// Get all keys
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key, localStorage.getItem(key));
}Storing Objects and Arrays
Local Storage only stores strings. To store objects or arrays, you need to convert them to JSON:
// Storing an object
const user = {
name: 'John Doe',
email: 'john@example.com',
age: 30,
preferences: {
theme: 'dark',
notifications: true
}
};
// Convert to JSON string before storing
localStorage.setItem('user', JSON.stringify(user));
// Retrieving and parsing the object
const storedUser = localStorage.getItem('user');
const userObject = JSON.parse(storedUser);
console.log(userObject.name); // "John Doe"
// Storing an array
const favorites = ['apple', 'banana', 'orange'];
localStorage.setItem('favorites', JSON.stringify(favorites));
// Retrieving the array
const storedFavorites = JSON.parse(localStorage.getItem('favorites'));
console.log(storedFavorites[0]); // "apple"Practical Example: Theme Switcher
Here's a complete example that saves and applies a user's theme preference:
<!DOCTYPE html>
<html>
<head>
<style>
body {
transition: background-color 0.3s, color 0.3s;
padding: 20px;
font-family: Arial, sans-serif;
}
body.light {
background-color: white;
color: black;
}
body.dark {
background-color: #1a1a1a;
color: white;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
margin: 10px 5px;
}
</style>
</head>
<body>
<h1>Theme Switcher Demo</h1>
<p>Your theme preference is saved in Local Storage!</p>
<button id="lightBtn">Light Theme</button>
<button id="darkBtn">Dark Theme</button>
<script>
// Load saved theme on page load
function loadTheme() {
const savedTheme = localStorage.getItem('theme') || 'light';
document.body.className = savedTheme;
}
// Save and apply theme
function setTheme(theme) {
localStorage.setItem('theme', theme);
document.body.className = theme;
}
// Event listeners
document.getElementById('lightBtn').addEventListener('click', () => {
setTheme('light');
});
document.getElementById('darkBtn').addEventListener('click', () => {
setTheme('dark');
});
// Load theme when page loads
loadTheme();
</script>
</body>
</html>Session Storage vs Local Storage
Web Storage includes two similar but distinct storage options:
// LOCAL STORAGE - persists forever (until manually cleared)
localStorage.setItem('username', 'John');
// Data survives browser restart
// SESSION STORAGE - persists only for the session
sessionStorage.setItem('tempData', 'temporary');
// Data is cleared when tab/window is closed
// Both have the same API
sessionStorage.getItem('tempData');
sessionStorage.removeItem('tempData');
sessionStorage.clear();| Feature | Local Storage | Session Storage |
|---|---|---|
| Persistence | Forever (until cleared) | Until tab/window closes |
| Scope | Shared across all tabs | Limited to single tab |
| Storage Size | ~5-10MB | ~5-10MB |
| Use Case | User preferences, settings | Temporary form data, one-time info |
Storage Events
You can listen for changes to Local Storage across different tabs/windows:
// Listen for storage changes in other tabs
window.addEventListener('storage', function(e) {
console.log('Storage changed!');
console.log('Key:', e.key);
console.log('Old value:', e.oldValue);
console.log('New value:', e.newValue);
console.log('URL:', e.url);
// Update UI based on changes
if (e.key === 'theme') {
document.body.className = e.newValue;
}
});
// Note: This event only fires in OTHER tabs/windows,
// not in the tab that made the changeUseful Helper Functions
Here are some utility functions to make working with Local Storage easier:
// Storage helper object
const storage = {
// Set item (handles objects automatically)
set(key, value) {
try {
const serialized = JSON.stringify(value);
localStorage.setItem(key, serialized);
return true;
} catch (e) {
console.error('Error saving to localStorage', e);
return false;
}
},
// Get item (parses objects automatically)
get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
if (item === null) return defaultValue;
return JSON.parse(item);
} catch (e) {
console.error('Error reading from localStorage', e);
return defaultValue;
}
},
// Remove item
remove(key) {
localStorage.removeItem(key);
},
// Clear all
clear() {
localStorage.clear();
},
// Get all items as object
getAll() {
const items = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
items[key] = this.get(key);
}
return items;
}
};
// Usage
storage.set('user', { name: 'John', age: 30 });
const user = storage.get('user');
console.log(user.name); // "John"Storage Limits and Quota
Different browsers have different storage limits. Here's how to check available space:
// Check storage quota (modern browsers)
if (navigator.storage && navigator.storage.estimate) {
navigator.storage.estimate().then(estimate => {
const usedMB = (estimate.usage / (1024 * 1024)).toFixed(2);
const quotaMB = (estimate.quota / (1024 * 1024)).toFixed(2);
console.log(`Using ${usedMB} MB of ${quotaMB} MB`);
console.log(`${((estimate.usage / estimate.quota) * 100).toFixed(2)}% used`);
});
}
// Handle quota exceeded errors
try {
localStorage.setItem('key', 'very large data...');
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.error('Storage quota exceeded!');
// Clear old data or notify user
}
}Security Considerations
- Never store sensitive data: Don't store passwords, credit card numbers, or personal information in Local Storage
- XSS vulnerability: Data in Local Storage is accessible via JavaScript, making it vulnerable to XSS attacks
- Not encrypted: Data is stored in plain text and can be viewed in browser developer tools
- Same-origin policy: Only accessible from the same protocol, domain, and port
Best Practices
- Always use try-catch: Storage operations can fail in private browsing mode or when quota is exceeded
- Validate retrieved data: Check if data exists and is in the expected format
- Use meaningful keys: Prefix keys with your app name to avoid conflicts (e.g., 'myApp_theme')
- Clean up old data: Remove unused items periodically
- Consider storage limits: Don't store large amounts of data
- Provide fallbacks: App should work even if storage is disabled
Key Takeaways
- Local Storage stores key-value pairs that persist indefinitely
- Use setItem(), getItem(), removeItem(), and clear() methods
- Local Storage only stores strings - use JSON.stringify() and JSON.parse() for objects
- Session Storage is similar but only lasts for the browser session
- Storage limit is typically 5-10MB per domain
- Never store sensitive or personal data in Local Storage
- Always wrap storage operations in try-catch blocks
What's Next?
Now that you understand Local Storage, you can create web applications that remember user preferences and maintain state across sessions. In the next lesson, we'll explore Web Workers, which allow you to run JavaScript in background threads for better performance.