32  Browser Storage Types Overview

Browser storage is crucial for creating modern web applications that can persist data, work offline, and provide better user experiences. Let me break down each storage type with their characteristics and use cases.

32.1 Storage Types Comparison Diagram

┌────────────────────────────────────────────────────────────────┐
│                    Browser Storage Types                       │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ localStorage │  │sessionStorage│  │   Cookies    │          │
│  ├──────────────┤  ├──────────────┤  ├──────────────┤          │
│  │ ≈10MB        │  │ ≈5-10MB      │  │ ≈4KB         │          │
│  │ Permanent    │  │ Tab lifetime │  │ Expirable    │          │
│  │ Client only  │  │ Client only  │  │ Client/Server│          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│                                                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │  IndexedDB   │  │  Cache API   │  │   WebSQL     │          │
│  ├──────────────┤  ├──────────────┤  ├──────────────┤          │
│  │ Unlimited*   │  │ Unlimited*   │  │ (Deprecated) │          │
│  │ Permanent    │  │ Permanent    │  │              │          │
│  │ Async/NoSQL  │  │ Async/HTTP   │  │              │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│                                                                │
│  * Subject to browser quota management                         │
└────────────────────────────────────────────────────────────────┘

32.2 localStorage

What it is: Key-value storage that persists even after browser is closed.

Characteristics: - Storage limit: ~5-10MB (varies by browser) - Synchronous API (blocks main thread) - Stores only strings - Domain-specific (same-origin policy) - No expiration date

When to use: - User preferences (theme, language, settings) - Form data auto-save - Shopping cart contents - Simple app state that should persist

// Store data
localStorage.setItem('userTheme', 'dark');
localStorage.setItem('userData', JSON.stringify({name: 'John', age: 30}));

// Retrieve data
const theme = localStorage.getItem('userTheme');
const userData = JSON.parse(localStorage.getItem('userData'));

// Remove data
localStorage.removeItem('userTheme');
localStorage.clear(); // Remove all

32.3 sessionStorage

What it is: Similar to localStorage but data expires when tab closes.

Characteristics: - Storage limit: ~5-10MB - Synchronous API - Tab-specific (not shared between tabs) - Cleared when tab/window closes - Survives page refresh

When to use: - Temporary form data during multi-step process - One-time authentication tokens - Tab-specific UI state - Temporary filters or search parameters

// Same API as localStorage
sessionStorage.setItem('tempFormData', JSON.stringify(formData));
sessionStorage.getItem('tempFormData');
sessionStorage.removeItem('tempFormData');

32.4 Cookies

What it is: Small text files sent with HTTP requests.

Characteristics: - Storage limit: ~4KB per cookie - Sent with every HTTP request (increases bandwidth) - Can be accessed by server - Supports expiration dates - Can be HTTP-only (not accessible via JavaScript)

When to use: - Authentication tokens (HTTP-only) - Server-side session management - Tracking and analytics - Cross-subdomain data sharing

// Set cookie
document.cookie = "username=John; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/";

// Read cookies (returns all as string)
const cookies = document.cookie;

// Delete cookie (set past expiration)
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";

32.5 IndexedDB

What it is: Low-level API for storing large amounts of structured data.

Characteristics: - Storage limit: Typically 50% of free disk space - Asynchronous API (doesn’t block main thread) - Supports transactions - Can store complex data types (not just strings) - NoSQL database in browser

When to use: - Offline-first applications - Large datasets (images, videos, documents) - Complex data relationships - PWA (Progressive Web App) data storage

// Open database
const request = indexedDB.open('MyDatabase', 1);

request.onsuccess = (event) => {
  const db = event.target.result;
  
  // Create transaction and store
  const transaction = db.transaction(['users'], 'readwrite');
  const store = transaction.objectStore('users');
  
  // Add data
  store.add({ id: 1, name: 'John', email: 'john@example.com' });
};

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  // Create object store
  const objectStore = db.createObjectStore('users', { keyPath: 'id' });
  objectStore.createIndex('name', 'name', { unique: false });
};

32.6 Cache API

What it is: Storage for HTTP request/response pairs, primarily for Service Workers.

Characteristics: - Designed for caching network requests - Asynchronous (Promise-based) - Works with Service Workers - Stores Response objects

When to use: - PWA offline functionality - Caching API responses - Static asset caching - Network performance optimization

// In Service Worker
caches.open('v1').then(cache => {
  // Add resources to cache
  cache.addAll([
    '/index.html',
    '/styles.css',
    '/script.js'
  ]);
  
  // Cache a fetch response
  cache.put(request, response);
});

// Retrieve from cache
caches.match('/index.html').then(response => {
  if (response) {
    // Use cached version
    return response;
  }
  // Fetch from network
  return fetch('/index.html');
});

32.7 Decision Tree for Storage Selection

Start: What type of data do you need to store?
│
├─ Small, simple data (<5MB)?
│  │
│  ├─ Need server access? → Cookies
│  │
│  ├─ Should persist after tab close? → localStorage
│  │
│  └─ Only during session? → sessionStorage
│
├─ Large or complex data?
│  │
│  ├─ Network requests/responses? → Cache API
│  │
│  └─ Structured application data? → IndexedDB
│
└─ Authentication tokens?
   │
   └─ HTTP-only cookie (most secure)

32.8 Best Practices

  1. Always check storage availability:
if (typeof(Storage) !== "undefined") {
  // localStorage/sessionStorage supported
}

if ('indexedDB' in window) {
  // IndexedDB supported
}
  1. Handle storage quota errors:
try {
  localStorage.setItem('test', 'data');
} catch (e) {
  if (e.name === 'QuotaExceededError') {
    // Storage full, clean up old data
  }
}
  1. Encrypt sensitive data before storing client-side

  2. Use libraries for complex storage:

    • localForage - Simple API over IndexedDB/WebSQL/localStorage
    • Dexie.js - Wrapper for IndexedDB
    • PouchDB - Client-side database with sync capabilities