Cookies vs localStorage — Browser Storage Comparison
Cookies and localStorage are both browser-based storage mechanisms for client-side data, but they have fundamentally different capabilities and security properties. Cookies are automatically sent with HTTP requests (making them accessible server-side) and have rich security attributes. localStorage is a simple key-value store accessible only to JavaScript on the same origin, with no automatic server transmission. Choosing between them depends primarily on whether the server needs to access the data.
Comparison Table
| Aspect | Cookies | localStorage |
|---|---|---|
| Server access | Automatically sent with every HTTP request to the server | Never sent to server; JavaScript access only |
| Size limit | 4 KB per cookie | 5–10 MB per origin |
| Expiration | Session (tab close) or explicit date | Persists until explicitly cleared; no built-in expiry |
| HttpOnly flag | Can be set HttpOnly — inaccessible to JavaScript | Always accessible to JavaScript; no HttpOnly equivalent |
| XSS risk | HttpOnly cookies cannot be stolen by XSS | All localStorage data accessible to injected scripts |
| CSRF risk | Vulnerable if not using SameSite attribute | Not sent automatically; no CSRF risk |
| Cross-tab | Shared across all tabs for the domain | Shared across all tabs for the origin |
| Subdomain access | Can be scoped to parent domain and all subdomains | Same-origin only; not shared across subdomains |
When to Use Cookies
Use cookies for session tokens, authentication credentials, and any data the server needs to read. The HttpOnly flag makes session cookies inaccessible to JavaScript, protecting them from XSS attacks. Cookies with SameSite=Strict prevent CSRF. The server can set and read cookies directly, making them the right choice for stateful authentication in traditional web applications.
When to Use localStorage
Use localStorage for client-side UI state: theme preferences, cached API responses, draft text, user interface settings, and data that only the front-end JavaScript needs. localStorage's 5–10 MB storage limit and lack of network overhead make it suitable for caching moderately large datasets client-side. Never store authentication tokens in localStorage — they are accessible to any JavaScript on the page.
Convert Between Cookies and localStorage
FAQ
- Is it safe to store JWT tokens in localStorage?
- It is debated. localStorage JWTs are vulnerable to XSS — any injected script can steal the token. Cookies with HttpOnly prevent this. However, localStorage avoids CSRF. The general recommendation for high-security apps is HttpOnly cookies with SameSite=Strict. For SPAs with a public API and no sensitive user data, localStorage JWTs are pragmatically acceptable.
- What is sessionStorage and how does it differ from localStorage?
- sessionStorage works exactly like localStorage but is cleared when the browser tab is closed. It is not shared between tabs. Use sessionStorage for truly temporary state that should not persist, like multi-step form progress in a single session.
- What is IndexedDB and when should I use it?
- IndexedDB is a browser database for storing structured data with indexes and transactions. Use it when you need to store more than 10 MB of data, need complex queries, or want to store binary data (files, blobs). Libraries like Dexie.js provide a friendly API around the complex IndexedDB interface.