Browser State Systems

Written by Backbone Tutorials Team

Last updated: June 2026 · 10 min read

The state management guide treated state as a design problem inside your app. But the browser itself offers a surprising number of places to put state, each with its own lifetime, scope, size limit, and security profile, and choosing the wrong one causes problems no amount of clean app code can fix. Put a draft in memory and a reload loses it; put a token in the wrong store and you create a risk; put a large dataset in the wrong API and the app stalls. Knowing the browser's state systems is what lets you put each thing where it belongs.

This guide maps those systems and how to choose between them. It complements state management and the platform view in frontend systems.

State locations by lifetime From shortest to longest lived: in-memory, the URL, sessionStorage, then localStorage, IndexedDB, and cookies. In-memorylost on reload URLshareable sessionStorageper tab localStoragepersists IndexedDBlarge + cookies shorter lived ← → longer lived
State locations roughly ordered by lifetime, from in-memory through the URL and Web Storage to IndexedDB and cookies.

Where state can live in the browser

The browser is not one storage bin but several, each designed for a different job. Before choosing, it helps to see the whole menu rather than reaching for the one you happen to know.

A map of state locations

State can live in JavaScript memory, in the URL, in Web Storage, in IndexedDB, in cookies, in the HTTP cache, and effectively in the DOM itself. They differ along a few axes: how long the state survives, who can see it, how much it can hold, and whether it ever leaves the browser. Almost every storage mistake is really a mismatch on one of those axes, so the rest of this guide walks the main options and what each is good for.

In-memory and the URL

The two lightest places to keep state sit at opposite ends of permanence. One vanishes the instant the page reloads; the other rides along in the address bar.

Ephemeral memory versus shareable URL

In-memory state, ordinary JavaScript variables and your app's store, is fast and private to the page, but it is gone on reload or navigation, which is exactly right for transient things like an open menu. The URL, by contrast, persists across reloads and can be shared or bookmarked, making it the perfect home for view state like the current page, a search query, or a selected tab, the idea the routing guide built on. Reach for memory when losing the state is fine, and the URL when the state should survive and be shareable.

Web Storage: localStorage and sessionStorage

When you need to keep small amounts of data on the client across visits, Web Storage is the simplest tool. It is a synchronous key-value store scoped to your origin, in two flavours.

Persistent versus per-session storage

// localStorage: persists until cleared
localStorage.setItem('theme', 'dark');
var theme = localStorage.getItem('theme');

// sessionStorage: cleared when the tab closes
sessionStorage.setItem('draftId', id);

Both store strings under keys, per origin. localStorage persists until explicitly cleared, so it suits preferences like a theme; sessionStorage lasts only for the tab and is wiped when it closes, which suits a short-lived draft or wizard step. The caveats are real: the API is synchronous, so large reads and writes can block the main thread, the space is limited to a few megabytes, and you should not keep sensitive data here, since any script on the page can read it.

IndexedDB for structured data

Web Storage runs out of room and structure quickly. When you need to hold real datasets, query them, or work offline, the browser provides a proper database.

Large, structured, offline-capable data

IndexedDB is an asynchronous, transactional store for large amounts of structured data, with indexes you can query and far higher capacity than Web Storage. Because it is asynchronous, it does not block the main thread the way a big localStorage write would, which matters for the responsiveness the interactive apps guide stressed. Its API is lower level, so teams often wrap it in a small library, but it is the right foundation for caching server data, supporting offline use, or storing anything beyond a handful of simple values.

Cookies and the server

Every store so far stays on the client. Cookies are different in one decisive way: they travel to the server with each request, which is both their purpose and their constraint.

Cookies travel to the server

Because cookies are sent on every matching request, they exist mainly to carry data the server needs, classically a session or authentication identifier, rather than client-side app state. They are small, and that automatic transmission has a cost, so they are a poor place for general data. Their security flags matter: HttpOnly hides a cookie from JavaScript, Secure restricts it to HTTPS, and SameSite limits cross-site sending. For a session token specifically, an HttpOnly cookie is usually safer than Web Storage, precisely because scripts cannot read it.

Choosing where state lives

With the options mapped, the decision becomes a short series of questions rather than a habit. Matching the store to the requirement is the whole skill.

Match the store to the requirement

Ask how long the state must live, who needs to see it, how big it is, and whether it is sensitive. Ephemeral and private goes in memory; shareable view state goes in the URL; small persistent preferences go in Web Storage, per tab or persistent as needed; large or structured or offline data goes in IndexedDB; and data the server must receive each request goes in a cookie, with the right flags. Decide deliberately on those axes and state lands in the right place, instead of everything piling into localStorage because it is familiar. The final guide in this cluster pulls the performance thread together, covering frontend performance as a whole.

Frequently Asked Questions

Where should I store state in the browser?

It depends on lifetime and scope. Use in-memory state for ephemeral things, the URL for view state you want shareable, Web Storage for small persistent client data, IndexedDB for large or structured or offline data, and cookies for data the server needs on each request.

What is the difference between localStorage and sessionStorage?

Both are per-origin key-value stores with a string-based, synchronous API. localStorage persists until it is explicitly cleared, surviving reloads and restarts, while sessionStorage lasts only for the tab session and is cleared when that tab is closed.

When should I use IndexedDB instead of localStorage?

Use IndexedDB when you need to store a large amount of structured data, query it, or support offline use. localStorage is small, synchronous, and stores only strings, so it suits simple key-value preferences rather than substantial datasets.

Should I store authentication tokens in localStorage?

It is risky, because any script running on the page can read localStorage, so a cross-site scripting flaw exposes the token. For session tokens, an HttpOnly cookie is generally safer, since scripts cannot read it, though the right choice depends on your overall security design.

Read next: back to the Frontend Architecture hub, or revisit state management for state inside the app.

Want to see state wired into views?

The complete Backbone guide shows models and collections that hold and persist app data.

Explore the Backbone Guide →