// apis · Web Platform Advent #6
localStorage vs sessionStorage: la API Web Storage explicada
Cuándo usar localStorage frente a sessionStorage — diferencias de duración y alcance, sus límites de tamaño, cómo guardar JSON con seguridad y reaccionar al evento storage.
La API Web Storage le da al navegador dos almacenes clave-valor sencillos — localStorage y sessionStorage — para guardar pequeñas cantidades de datos en el dispositivo del usuario. Ambos comparten exactamente la misma API; solo se diferencian en cuánto viven los datos y quién puede verlos.
La API compartida
Ambos objetos exponen los mismos cinco métodos, y los dos guardan solo cadenas:
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme'); // 'dark'
localStorage.removeItem('theme');
localStorage.clear(); // borrar todo
console.log(localStorage.length); // número de claves Leer una clave que no existe devuelve null, así que puedes prever un valor por defecto con ||:
const theme = localStorage.getItem('theme') || 'light'; La única diferencia real: la duración
Toda la decisión cabe en una frase. localStorage persiste hasta que lo borras — sobrevive a recargas, al cierre de pestañas y al reinicio del navegador. sessionStorage vive solo mientras viva la pestaña: cierra la pestaña y los datos desaparecen, y una segunda pestaña en el mismo sitio obtiene su propio almacén separado.
window, así que localStorage y window.localStorage se refieren exactamente a lo mismo.Guardar objetos: stringify y parse
Como el almacenamiento solo guarda cadenas, cualquier dato estructurado debe pasar por JSON. Serializa al entrar, parsea al salir:
const user = { name: 'Ada', loggedIn: true };
// Guardar
localStorage.setItem('user', JSON.stringify(user));
// Releer
const saved = JSON.parse(localStorage.getItem('user'));
console.log(saved.name); // 'Ada' Envuelve JSON.parse en un try/catch cuando el valor pueda faltar o estar corrupto — parsear null o texto inválido lanza un error:
function readJSON(key, fallback) {
try {
const raw = localStorage.getItem(key);
return raw ? JSON.parse(raw) : fallback;
} catch {
return fallback;
}
} Alcance y el límite de tamaño
El almacenamiento se acota por origen (esquema + host + puerto): https://example.com y http://example.com no comparten datos. La cuota es de aproximadamente 5 MB por origen en la mayoría de navegadores — generosa para preferencias y cachés pequeñas, pero no es una base de datos. Superarla hace que setItem lance un QuotaExceededError, así que protege las escrituras grandes.
Reaccionar a los cambios entre pestañas
El evento storage se dispara en las otras pestañas del mismo origen cuando localStorage cambia — útil para sincronizar un cierre de sesión o un cambio de tema entre ventanas abiertas. Ten en cuenta que no se dispara en la pestaña que hizo el cambio, y que sessionStorage nunca lo activa:
window.addEventListener('storage', (event) => {
if (event.key === 'theme') {
applyTheme(event.newValue);
}
}); ¿Cuál deberías usar?
| localStorage | sessionStorage | |
|---|---|---|
| Duración | Hasta borrarlo explícitamente | Hasta cerrar la pestaña |
| Compartido entre pestañas | Sí (mismo origen) | No (por pestaña) |
| Sobrevive a la recarga | Sí | Sí |
Dispara el evento storage | Sí | No |
| Uso típico | Tema, ajustes, «recuérdame» | Borradores de formulario, pasos de asistente |
Recurre a localStorage cuando el dato deba permanecer entre visitas, y a sessionStorage cuando solo tenga sentido para la pestaña actual. Para cualquier cosa sensible — tokens, contraseñas, datos personales — ninguno es apropiado: ambos son legibles por cualquier script de la página, así que mantén los secretos completamente fuera del Web Storage.