Server-side frameworks like Django or Spring primarily manage session handling on the server and identify clients through cookies. It's convenient since the server manages the state.
However, in SPA (Single Page Application) environments like React, Vue, or Angular, the client (browser) takes on many roles. Communication with the server mainly involves exchanging data via API, while the user's state and UI settings are often managed directly by the client.
At this point, you need to decide "where" to store the data, and the browser provides several storage options for this. Understanding the characteristics and purposes of each storage type is key to effective SPA development.
Today, we will look at the main browser storage options: cookies, local storage, session storage, and IndexedDB.
1. Cookie
Cookies are the original form of browser storage, originally designed to maintain state between the server and the client.
-
Characteristics:
-
Small Size: Limited to about 4KB, which is very small.
-
Server Transmission: The biggest feature of cookies. Cookies are automatically included in all HTTP requests sent to the server. This is useful when the server needs to know the client's state, but unnecessary data transmission can degrade performance.
-
Expiration: You can set expiration dates and times through the
ExpiresorMax-Ageattributes. If not set, it behaves as a session cookie (deleted upon browser closure). -
Security Options: Security settings such as
HttpOnly(prevents JavaScript access) andSecure(transmitted only over HTTPS) can be applied.
-
-
Main Uses:
-
Authentication: Used to store login authentication tokens (JWT, etc.) issued by the server, allowing the server to identify the user as they navigate between pages (especially used with the
HttpOnlyoption). -
User Tracking and Advertising: Used to track a user's visit history or behavior patterns (e.g., Google Analytics).
-
'Don't Show Again Today' Popups
-
2. Local Storage
Part of the Web Storage API introduced in HTML5, local storage was created to address the shortcomings of cookies (small size, automatic server transmission).
-
Characteristics:
-
Large Size: While it varies by browser, it generally offers a generous capacity of 5MB to 10MB.
-
No Server Transmission: Local storage saves data only on the client and not automatically transmitted to the server. It's good for storing data that the server doesn't need to know.
-
Persistence: Data is stored permanently. Unless the user manually clears the browser cache or calls
localStorage.removeItem()in JavaScript, the data does not disappear. -
Easy API: Provides an easy-to-use API like
localStorage.setItem('key', 'value')andlocalStorage.getItem('key'). (Only strings can be stored)
-
-
Main Uses:
-
User Settings Storage: Used to save user-selected UI settings like dark mode/light mode or language settings.
-
Non-sensitive Data Storage: To store lists of content last viewed by the user, autosave features, etc.
-
Data Caching: Used to cache less frequently changed data from API responses to reduce unnecessary requests.
-
3. Session Storage
Shares almost all features with local storage, but there is a critical difference in the life cycle of the data.
-
Characteristics:
-
Large Size: Similar to local storage, it offers about 5MB of capacity.
-
No Server Transmission: Data is stored only on the client.
-
Session-based Life Cycle: Data is limited to the current browser tab (or window). Closing the tab immediately deletes all data in session storage.
-
Data Isolation: Even for the same domain, data is not shared across different tabs.
-
-
Main Uses:
-
One-time Data Storage: Used to store information that is only needed for the current tab.
-
Temporary Form Data: When filling out a multi-step registration form or survey, used to temporarily store input data until the user closes the tab.
-
Data Persistence during Refresh: Data should persist during page refresh but disappear when the tab is closed.
-
4. IndexedDB
While local/session storage is a simple key-value store, IndexedDB is a full-fledged transactional database system existing within the browser.
-
Characteristics:
-
Large Storage: Can store very large amounts of data, from hundreds of MB to several GB, as allowed by the user's disk space (varies by browser policy).
-
Diverse Data Types: Can store not only strings but also JavaScript objects, files (Blobs), arrays, and more complex structured data.
-
Transaction Support: Ensures data integrity and consistency. Allows multiple operations to be processed as a single unit.
-
Asynchronous API: All operations are handled asynchronously. This maintains app responsiveness while reading and writing large amounts of data without blocking the main UI thread.
-
Index Support: Enables very fast searching of data by creating indexes on specific fields.
-
-
Drawbacks:
- Complex API: The API is much more complex and difficult to use compared to
localStorage. (Because of this, it is often used with wrapper libraries likeDexie.jsoridb.)
- Complex API: The API is much more complex and difficult to use compared to
-
Main Uses:
-
Offline Web Applications (PWA): Used to store core data in apps that must operate without network connections (e.g., offline document editors).
-
State Caching for Large Applications: Used in applications like Gemini or ChatGPT to save previous conversation histories in the browser or manage complex user data.
-
Temporary Storage of User-generated Content: Safely stores long texts, image editing data, etc., before uploading to the server.
-
5. Comparison at a Glance

The characteristics of the four storage types can be summarized in the following table.
| Criteria | Cookie | Local Storage | Session Storage | IndexedDB |
|---|---|---|---|---|
| Size | ~ 4KB | ~ 5-10MB | ~ 5MB | ~ GB+ (Large) |
| Expiration | Manually set | Permanent | On tab close | Permanent |
| Server Transmission | Yes (automatic) | No (client-only) | No (client-only) | No (client-only) |
| Access Scope | Same domain | Same origin | Current tab | Same origin |
| Data Type | String | String | String | Objects, Files, Blobs, etc. |
| API | Sync (Complex) | Sync (Simple) | Sync (Simple) | Async (Complex) |
| Search Functionality | No | No | No | Yes (using indexes) |
6. Conclusion: When and What to Use?
When developing SPAs like React, it’s helpful to clearly distinguish the purposes of these four storage types.
-
Cookie:
-
Used for data that the server must know (e.g., security-sensitive authentication tokens).
-
It’s good to protect tokens with the
HttpOnlyoption to guard against XSS attacks.
-
-
Local Storage:
-
Used for simple data that must persist even after the user closes and opens the browser.
-
(e.g., user UI theme settings, language selection).
-
-
Session Storage:
-
Used for temporary data that is only required during the current operation (tab).
-
(e.g., temporarily saving while filling out a multi-step form).
-
-
IndexedDB:
-
Used when structured large data or offline support is needed.
-
(e.g., complex app states, caching conversation histories, offline document data).
-
Important Security Note: Local Storage, Session Storage, and IndexedDB can be easily accessed via JavaScript. This makes them vulnerable to XSS (Cross-Site Scripting) attacks. Never store passwords, personal identification information, or sensitive authentication tokens here. (Using
HttpOnlycookies for authentication tokens is the safest approach.)
There are no comments.