Have you ever visited a website, set your preferences or dark mode, then come back the next day to find all your settings still saved? That can be done using Local Storage — a built-in browser feature that lets web applications store data directly in the user's browser. No database, no server — the data is stored locally and persistently.
What Is Local Storage?
Local Storage is part of the Web Storage API that lets us store data in key-value format inside the browser. The stored data is persistent — it won't disappear even if the browser is closed or the computer is restarted. Each domain has its own separate storage space, with a capacity of roughly 5-10 MB per domain.
- Local Storage — data stays until it is manually deleted.
- Session Storage — data is lost when the tab/browser is closed.
Storing Data (setItem)
Use localStorage.setItem(key, value) to store data. Keep in mind that the value must be a string:
// Store simple data (string)
localStorage.setItem('theme', 'dark');
localStorage.setItem('language', 'english');
localStorage.setItem('version', '2.1.0');
// Store a number (automatically converted to a string)
localStorage.setItem('volume', 75);
// Store an object or array — it MUST be converted to JSON first
const settings = {
theme: 'dark',
language: 'en',
notifications: true,
fontSize: 16
};
localStorage.setItem('settings', JSON.stringify(settings));
// Store an array
const searchHistory = ['javascript', 'react', 'node.js'];
localStorage.setItem('history', JSON.stringify(searchHistory));
Retrieving Data (getItem)
Use localStorage.getItem(key) to retrieve data. If the key does not exist, the result is null:
// Retrieve simple data
const theme = localStorage.getItem('theme');
console.log(theme); // 'dark'
// Retrieve data that does not exist
const color = localStorage.getItem('color');
console.log(color); // null
// Retrieve an object — it MUST be parsed from JSON
const settingsRaw = localStorage.getItem('settings');
const settings = JSON.parse(settingsRaw);
console.log(settings.theme); // 'dark'
console.log(settings.notifications); // true
// A safe approach if the data might be null
const historyRaw = localStorage.getItem('history');
const history = historyRaw ? JSON.parse(historyRaw) : [];
console.log(history); // ['javascript', 'react', 'node.js'] or []
Deleting Data
// Delete a single item by key
localStorage.removeItem('language');
// Delete ALL data in Local Storage (be careful!)
localStorage.clear();
// Check the number of stored items
console.log(localStorage.length); // number of keys
// Loop through all existing keys
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
console.log(`${key}: ${value}`);
}
Real-World Example: Persistent Dark Mode
A common implementation is saving the user's theme preference:
// When the page loads, apply the stored theme
function applyTheme() {
const theme = localStorage.getItem('theme') || 'light'; // default: light
document.body.classList.toggle('dark-mode', theme === 'dark');
document.getElementById('btn-theme').textContent =
theme === 'dark' ? '☀️ Light Mode' : '🌙 Dark Mode';
}
// Toggle the theme when the button is clicked
function toggleTheme() {
const currentTheme = localStorage.getItem('theme') || 'light';
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
localStorage.setItem('theme', newTheme);
applyTheme();
}
document.getElementById('btn-theme').addEventListener('click', toggleTheme);
document.addEventListener('DOMContentLoaded', applyTheme);
Real-World Example: Storing a To-Do List
const STORAGE_KEY = 'todo-list';
// Get data from storage
function getTasks() {
const data = localStorage.getItem(STORAGE_KEY);
return data ? JSON.parse(data) : [];
}
// Save data to storage
function saveTasks(taskList) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(taskList));
}
// Add a new task
function addTask(text) {
const tasks = getTasks();
tasks.push({ id: Date.now(), text, done: false });
saveTasks(tasks);
renderTasks();
}
// Mark as done
function toggleDone(id) {
const tasks = getTasks().map(t =>
t.id === id ? { ...t, done: !t.done } : t
);
saveTasks(tasks);
renderTasks();
}
// Render to the page
function renderTasks() {
const tasks = getTasks();
const ul = document.getElementById('task-list');
ul.innerHTML = tasks.map(t => `
<li style="text-decoration: ${t.done ? 'line-through' : 'none'}"
onclick="toggleDone(${t.id})">
${t.text}
</li>
`).join('');
}
document.addEventListener('DOMContentLoaded', renderTasks);
Limitations and Things to Watch Out For
- Local Storage can only store strings. Always use
JSON.stringify()for objects/arrays. - Do not store sensitive data such as passwords or JWT tokens in Local Storage because it is vulnerable to XSS attacks.
- Capacity is limited to around 5-10 MB — not suitable for large data.
- Local Storage is synchronous, which can block the main thread if the data is too large.
Conclusion
Local Storage is an easy and fast solution for storing user data in the browser without a server. It is perfect for display preferences, temporary data, or lightweight application state. Always remember to use JSON.stringify() when storing and JSON.parse() when retrieving data in the form of objects or arrays, and avoid storing sensitive information in it.