JavaScript Curriculum
Remembering Things
easyA Nexus user sets their theme to dark, marks three lessons complete, and closes the browser. When they return tomorrow, everything is remembered. When they open a second tab, it shares the same progress. When they sign in on a new device, their data syncs from the server. Three different storage mechanisms handle these three different needs.
Data that survives the page
By default, JavaScript variables disappear when the page closes. Browser storage APIs provide persistence — data that survives refreshes, tab closes, even browser restarts.
Try the interactive simulator below, then use the comparison table to decide which mechanism fits each use case:
localStorage contents
localStorage
- •Persists forever — survives page closes, browser restarts
- •Scoped to origin (domain + protocol + port)
- •Synchronous — blocks the main thread if reading large data
- •~5MB limit. Strings only — JSON.stringify for objects
| localStorage | sessionStorage | Cookies | IndexedDB | |
|---|---|---|---|---|
| Capacity | ~5 MB | ~5 MB | ~4 KB | Hundreds of MB |
| Persistence | Until cleared | Tab close | Expiry date | Until cleared |
| Sent to server | Never | Never | Every request | Never |
| JS accessible | Yes | Yes | Yes (if no HttpOnly) | Yes |
| Data type | Strings only | Strings only | Strings only | Any (structured) |
| API style | Sync | Sync | document.cookie | Async (Promise) |
| Best use | User prefs, theme, token | Per-tab temp data | Auth sessions | Offline data, large blobs |
localStorage — the workhorse
localStorage persists until explicitly cleared. It's synchronous and stores strings only.
Storing objects — always use JSON
A common utility pattern used across every project:
sessionStorage — per-tab temporary storage
Same API as localStorage, but data is cleared when the tab closes. Each tab gets its own isolated sessionStorage — two tabs don't share it.
Use cases: multi-step form progress within a session, temporary UI state, scroll position, tab-specific filters.
Cookies — when you need the server
Cookies are the oldest browser storage mechanism. Unlike localStorage, cookies are sent to the server with every HTTP request — making them the right choice for authentication sessions.
In practice, most applications set authentication cookies from the server using Set-Cookie headers with HttpOnly (invisible to JavaScript, protects against XSS) and Secure (HTTPS only) flags. Never store sensitive data in JavaScript-accessible cookies.
IndexedDB — large structured data
For large datasets, binary files, or offline-first apps, IndexedDB is the answer. It's asynchronous, has no size restriction (browser-dependent, usually hundreds of MB), and stores any JavaScript value.
For IndexedDB, most real projects use the idb library which wraps the callback API in Promises.
Choosing the right storage
| Need | Use |
|---|---|
| User preferences (theme, language) | localStorage |
| Auth token (non-HttpOnly) | localStorage with care |
| Auth session cookie | Server-set HttpOnly cookie |
| Multi-step form state | sessionStorage |
| Per-tab state | sessionStorage |
| Large offline data | IndexedDB |
| Structured query support | IndexedDB |
Your challenge
savePreference and getPreference are the utility pair every real project needs. The key insight: JSON.stringify before saving (so objects survive the string-only constraint), JSON.parse after loading. Guard the get with ?? defaultValue for the missing-key case, and wrap parse in try/catch for malformed data. This pattern appears verbatim in production codebases.
Challenge
Write three functions: savePreference(key, value) that stores a value in localStorage. getPreference(key, defaultValue) that retrieves it — returning defaultValue if it isn't set. clearPreference(key) that removes it. For values that are objects or arrays, use JSON.stringify on save and JSON.parse on retrieval. Test by saving { theme: 'dark', fontSize: 16 } under the key 'ui-prefs', then reading it back.
Remembering Things
easyA Nexus user sets their theme to dark, marks three lessons complete, and closes the browser. When they return tomorrow, everything is remembered. When they open a second tab, it shares the same progress. When they sign in on a new device, their data syncs from the server. Three different storage mechanisms handle these three different needs.
Data that survives the page
By default, JavaScript variables disappear when the page closes. Browser storage APIs provide persistence — data that survives refreshes, tab closes, even browser restarts.
Try the interactive simulator below, then use the comparison table to decide which mechanism fits each use case:
localStorage contents
localStorage
- •Persists forever — survives page closes, browser restarts
- •Scoped to origin (domain + protocol + port)
- •Synchronous — blocks the main thread if reading large data
- •~5MB limit. Strings only — JSON.stringify for objects
| localStorage | sessionStorage | Cookies | IndexedDB | |
|---|---|---|---|---|
| Capacity | ~5 MB | ~5 MB | ~4 KB | Hundreds of MB |
| Persistence | Until cleared | Tab close | Expiry date | Until cleared |
| Sent to server | Never | Never | Every request | Never |
| JS accessible | Yes | Yes | Yes (if no HttpOnly) | Yes |
| Data type | Strings only | Strings only | Strings only | Any (structured) |
| API style | Sync | Sync | document.cookie | Async (Promise) |
| Best use | User prefs, theme, token | Per-tab temp data | Auth sessions | Offline data, large blobs |
localStorage — the workhorse
localStorage persists until explicitly cleared. It's synchronous and stores strings only.
Storing objects — always use JSON
A common utility pattern used across every project:
sessionStorage — per-tab temporary storage
Same API as localStorage, but data is cleared when the tab closes. Each tab gets its own isolated sessionStorage — two tabs don't share it.
Use cases: multi-step form progress within a session, temporary UI state, scroll position, tab-specific filters.
Cookies — when you need the server
Cookies are the oldest browser storage mechanism. Unlike localStorage, cookies are sent to the server with every HTTP request — making them the right choice for authentication sessions.
In practice, most applications set authentication cookies from the server using Set-Cookie headers with HttpOnly (invisible to JavaScript, protects against XSS) and Secure (HTTPS only) flags. Never store sensitive data in JavaScript-accessible cookies.
IndexedDB — large structured data
For large datasets, binary files, or offline-first apps, IndexedDB is the answer. It's asynchronous, has no size restriction (browser-dependent, usually hundreds of MB), and stores any JavaScript value.
For IndexedDB, most real projects use the idb library which wraps the callback API in Promises.
Choosing the right storage
| Need | Use |
|---|---|
| User preferences (theme, language) | localStorage |
| Auth token (non-HttpOnly) | localStorage with care |
| Auth session cookie | Server-set HttpOnly cookie |
| Multi-step form state | sessionStorage |
| Per-tab state | sessionStorage |
| Large offline data | IndexedDB |
| Structured query support | IndexedDB |
Your challenge
savePreference and getPreference are the utility pair every real project needs. The key insight: JSON.stringify before saving (so objects survive the string-only constraint), JSON.parse after loading. Guard the get with ?? defaultValue for the missing-key case, and wrap parse in try/catch for malformed data. This pattern appears verbatim in production codebases.
Challenge
Write three functions: savePreference(key, value) that stores a value in localStorage. getPreference(key, defaultValue) that retrieves it — returning defaultValue if it isn't set. clearPreference(key) that removes it. For values that are objects or arrays, use JSON.stringify on save and JSON.parse on retrieval. Test by saving { theme: 'dark', fontSize: 16 } under the key 'ui-prefs', then reading it back.