localStorage vs sessionStorage: conceptos, ejemplos y mejores prácticas
1. Introducción al Web Storage API
El Web Storage API (también llamado Web Storage) es la solución nativa del navegador para almacenar datos del lado del cliente de forma persistente (localStorage) o por sesión (sessionStorage). Reemplaza a las cookies en la mayoría de los casos, ofreciendo mayor capacidad (hasta 5‑10 MB por origen) y una API mucho más sencilla.
2. ¿Qué es localStorage?
Almacena pares clave‑valor como string que persisten incluso después de cerrar el navegador. Los datos están disponibles para todas las pestañas y ventanas que compartan el mismo origen (protocolo, dominio y puerto).
// Guardar un valor
localStorage.setItem('theme', 'dark');
// Recuperar
const theme = localStorage.getItem('theme'); // "dark"
// Eliminar
localStorage.removeItem('theme');
// Vaciar todo el storage
localStorage.clear();
3. ¿Qué es sessionStorage?
Funciona idénticamente a localStorage pero su vida útil está limitada a la sesión del navegador. Cuando la pestaña o ventana se cierra, el contenido se elimina automáticamente.
// Guardar un valor temporal
sessionStorage.setItem('cart', JSON.stringify({items: []}));
// Recuperar
const cart = JSON.parse(sessionStorage.getItem('cart'));
4. Comparativa rápida
localStorage
- Persistente entre sesiones.
- Compartido entre todas las pestañas del mismo origen.
- Capacidad típica: 5‑10 MB.
- Se mantiene después de recargar o cerrar el navegador.
sessionStorage
- Válido sólo mientras la pestaña está abierta.
- No se comparte entre pestañas/ventanas.
- Capacidad similar a localStorage, pero se libera al cerrar.
- Ideal para datos temporales (carritos, formularios).
| Característica | localStorage | sessionStorage |
|---|---|---|
| Persistencia | Hasta que el usuario lo elimine | Duración de la sesión |
| Ámbito | Todo el origen (todas las pestañas) | Solo la pestaña actual |
| Límite de tamaño | ≈5 MB (varía por navegador) | ≈5 MB |
| Acceso desde Workers | Sí (en Service Workers) | No |
| Seguridad | Vulnerable a XSS | Igual, pero menos exposición temporal |
5. Casos de uso típicos
- Preferencias de UI: tema, idioma, modo oscuro.
- Estado de autenticación: token JWT (con precaución, nunca almacenar credenciales sensibles).
- Carritos de compra temporales: sessionStorage para mantener ítems mientras el usuario navega.
- Datos de formularios: guardado automático para evitar pérdida de información.
6. Ejemplos avanzados
6.1. Almacenar objetos JSON
const user = {
id: 42,
name: 'Ana Pérez',
roles: ['admin', 'editor']
};
// Serializar antes de guardar
localStorage.setItem('user', JSON.stringify(user));
// Recuperar y deserializar
const storedUser = JSON.parse(localStorage.getItem('user'));
console.log(storedUser.name); // "Ana Pérez"
6.2. Expiración de datos (pseudo‑TTL)
function setWithExpiry(key, value, ttlMs) {
const now = Date.now();
const item = { value, expiry: now + ttlMs };
localStorage.setItem(key, JSON.stringify(item));
}
function getWithExpiry(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
const item = JSON.parse(itemStr);
if (Date.now() > item.expiry) {
localStorage.removeItem(key);
return null; // expirado
}
return item.value;
}
// Uso: almacenar durante 10 minutos
setWithExpiry('sessionToken', 'abcd1234', 10 * 60 * 1000);
6.3. Fallback a cookies cuando el storage no está disponible
function isStorageSupported(type) {
try {
const storage = window[type];
const testKey = '__test__';
storage.setItem(testKey, '1');
storage.removeItem(testKey);
return true;
} catch (e) {
return false;
}
}
const storage = isStorageSupported('localStorage') ? localStorage : {
setItem: (k, v) => document.cookie = `${k}=${encodeURIComponent(v)}; path=/;`,
getItem: (k) => {
const match = document.cookie.match(new RegExp('(^| )' + k + '=([^;]+)'));
return match ? decodeURIComponent(match[2]) : null;
},
removeItem: (k) => document.cookie = `${k}=; Max-Age=0; path=/;`
};
7. Seguridad y consideraciones de privacidad
- Cross‑Site Scripting (XSS): cualquier script que se ejecute en la página puede leer/modificar el storage. Usa Content‑Security‑Policy (CSP) y sanitiza la entrada.
- Datos sensibles: nunca guardes contraseñas, números de tarjeta o tokens de refresco sin cifrado del lado del cliente.
- Same‑origin policy: el storage está aislado por origen, pero sub‑dominios comparten el mismo origen si comparten protocolo, host y puerto.
- Protección contra borrado accidental: implementa copias de seguridad en el servidor cuando la persistencia es crítica.
8. Rendimiento y limitaciones
El acceso a localStorage y sessionStorage es síncrono, lo que significa que una operación pesada puede bloquear el hilo principal. Para datos grandes, considera IndexedDB (asincrónico) o Cache Storage en Service Workers.
- Tamaño máximo: 5 MB en la mayoría de navegadores, pero Chrome permite hasta 10 MB en dispositivos de escritorio.
- Serialización: cada
setItemimplica convertir a string; evita almacenar objetos enormes sin necesidad. - Bloqueo del UI: usa
requestIdleCallbackosetTimeoutpara operaciones de escritura poco críticas.
9. Compatibilidad entre navegadores
El Web Storage API está soportado en todos los navegadores modernos (Chrome, Edge, Firefox, Safari, Opera) desde versiones muy antiguas. En entornos muy restrictivos (IE 8) se necesita un polyfill basado en cookies.
| Navegador | localStorage | sessionStorage |
|---|---|---|
| Chrome 1+ | ✔ | ✔ |
| Firefox 2+ | ✔ | ✔ |
| Safari 4+ | ✔ | ✔ |
| Edge 12+ | ✔ | ✔ |
| Internet Explorer 8+ | ✔ | ✔ |
10. Mejores prácticas recomendadas
- Usa
JSON.stringifyyJSON.parsepara objetos. - Implementa una capa de expiración si los datos deben caducar.
- Never store plain‑text credentials; encrypt if absolutely necessary.
- Valida y sanitiza siempre la entrada del usuario antes de guardarla.
- Limita la cantidad de datos a lo estrictamente necesario para evitar sobresaturar el storage.
- Utiliza
try / catchpara capturarQuotaExceededErrory actuar en consecuencia. - Prefiere
sessionStoragepara datos temporales ylocalStoragepara configuraciones persistentes. - Cuando necesites almacenar más de 10 MB o datos estructurados complejos, migra a IndexedDB.
11. Depuración y troubleshooting
Las herramientas de desarrollo de Chrome/Firefox incluyen una pestaña "Application" (Chrome) o "Storage" (Firefox) donde puedes inspeccionar el contenido de localStorage y sessionStorage. Para depurar programáticamente:
function debugStorage(storage) {
console.table(Object.keys(storage).map(key => ({key, value: storage.getItem(key)})));
}
// Ejemplo:
debugStorage(localStorage);
Si recibes QuotaExceededError, revisa el tamaño de los valores y considera limpiar datos obsoletos o usar sessionStorage en lugar de localStorage.
12. Alternativas al Web Storage
- IndexedDB: base de datos NoSQL del lado del cliente, asincrónica y con capacidad de varios cientos de MB.
- Cache Storage (Service Workers): ideal para almacenar respuestas HTTP y recursos estáticos.
- Cookies: limitadas a 4 KB, enviadas al servidor en cada request, útiles para información que debe ser leída por el backend.
Guía completa de localStorage y sessionStorage en JavaScript