JWT storage in browsers
October 6, 2026 · 14 min read
Single-page apps must decide where the access token lives after login. Browsers offer localStorage (persistent), sessionStorage (tab-scoped), and cookies (sent automatically on HTTP requests). Each choice changes XSS risk, logout behavior, and whether JavaScript can read the token at all.
Three browser storage mechanisms
- localStorage - Survives browser restarts until cleared; ~5 MB per origin; accessible to any script on the page.
- sessionStorage - Cleared when the tab closes; same script access model as localStorage.
- Cookies - Sent on matching requests; can be
HttpOnly(hidden from JS),Secure, andSameSite-restricted.
localStorage: persistent and convenient
Teams like localStorage because SPAs can attach Authorization: Bearer manually in fetch wrappers and tokens survive refresh. The downside is any XSS vulnerability - malicious script, compromised dependency, or inline injection - can read localStorage.getItem('token') and exfiltrate sessions.
If you use localStorage, invest heavily in CSP, dependency auditing, and sanitization. Treat XSS as session compromise, not a minor bug.
sessionStorage: temporary tab scope
sessionStorage limits persistence to the tab lifetime - useful for shared-computer kiosks or reducing accidental long-lived tokens on developer machines. It does not fix XSS: scripts in the tab still read the value. It only shortens the window if users close the tab.
Cookies: HttpOnly and automatic transport
Storing JWTs in HttpOnly, Secure, SameSite cookies keeps tokens off the JavaScript attack surface. The browser attaches them to same-site API calls; your backend must validate CSRF when using cookies (double-submit cookie, SameSite=Lax/Strict, or custom headers).
Cookie size limits (~4 KB per cookie) matter for bloated JWT payloads - trim claims or use reference tokens. Split refresh vs access token strategies: short-lived access in memory, refresh in HttpOnly cookie is a common hardened pattern.
What to pick in 2026
- High-security consumer apps → HttpOnly cookies + CSRF protection + short TTL.
- Third-party API SPAs with strict CORS → memory-only access token during session, refresh via backend-for-frontend.
- Internal admin tools with strong CSP → localStorage may be acceptable with monitoring.
Decode sample tokens locally with the JWT decoder to audit claim size before choosing cookie storage - never paste production secrets into untrusted sites.
FAQ
- Is localStorage ever OK for JWTs?
- Some teams accept it with strict CSP and low XSS surface. Prefer HttpOnly cookies when feasible.
- Does sessionStorage protect against XSS?
- No. It only limits persistence to the tab; scripts can still read the token.
- Can I use both cookie and localStorage?
- Avoid duplicate storage - it complicates logout and expands attack surface. Pick one strategy.
Related: JWT cookies vs localStorage · JWT security checklist · Common JWT mistakes