Skip to main content

Command Palette

Search for a command to run...

How to Deal with Local Storage in JavaScript

Published
4 min readView as Markdown

Local Storage is one of the simplest browser APIs—and also one of the most misunderstood. Developers often treat it like a mini-database, which leads to bugs, security issues, and messy code.

This article will help you understand:

  • What Local Storage actually is

  • When to use it (and when not to)

  • How to store, read, update, and delete data safely

  • Common mistakes and best practices

  • Real-world usage patterns


1. What Is Local Storage?

Local Storage is a browser-provided key–value storage mechanism that allows you to persist data across page reloads and browser restarts.

Key properties:

  • Data is stored as strings

  • Data persists until explicitly removed

  • Storage is scoped per origin (domain + protocol + port)

  • Max size is ~5–10 MB (browser dependent)

window.localStorage

You don’t need to import anything. It’s available globally in the browser.


2. Local Storage vs Session Storage (Quick Contrast)

FeatureLocal StorageSession Storage
Persists after refresh
Persists after browser close
ScopePer originPer tab
Storage limit~5–10MB~5MB

Use Local Storage for long-term persistence (preferences, tokens).
Use Session Storage for short-lived data (form drafts per tab).


3. Basic API: The Four Core Operations

Local Storage is extremely small in surface area:

localStorage.setItem(key, value)
localStorage.getItem(key)
localStorage.removeItem(key)
localStorage.clear()

Example

localStorage.setItem("theme", "dark")

const theme = localStorage.getItem("theme")
console.log(theme) // "dark"

localStorage.removeItem("theme")

localStorage.clear() // removes everything for this origin

⚠️ Important: Values are always stored as strings.


4. Storing Objects and Arrays (Critical Concept)

Since Local Storage stores only strings, objects must be serialized.

❌ Wrong

localStorage.setItem("user", { name: "Alex" })

This stores:

"[object Object]"

✅ Correct Way (JSON)

const user = { name: "Alex", age: 30 }

localStorage.setItem("user", JSON.stringify(user))

Reading It Back

const storedUser = JSON.parse(localStorage.getItem("user"))
console.log(storedUser.name) // "Alex"

🧠 Mental model:

Local Storage does not understand JavaScript objects.
You must convert objects → strings → objects.


5. Safe Read Pattern (Avoid Crashes)

JSON.parse(null) throws an error.

❌ Risky

const user = JSON.parse(localStorage.getItem("user"))

✅ Safe Pattern

const raw = localStorage.getItem("user")
const user = raw ? JSON.parse(raw) : null

Even better:

function getFromStorage(key, defaultValue) {
  const raw = localStorage.getItem(key)
  return raw ? JSON.parse(raw) : defaultValue
}

6. Updating Existing Data

You cannot partially update Local Storage data. You must:

  1. Read

  2. Modify

  3. Write back

Example: Updating User Age

const user = JSON.parse(localStorage.getItem("user"))
user.age += 1

localStorage.setItem("user", JSON.stringify(user))

🧠 Think of Local Storage as:

“Read → change → overwrite”


7. Removing Specific Values vs Clearing Everything

Remove one key

localStorage.removeItem("user")

Clear everything (dangerous)

localStorage.clear()

⚠️ Warning:
clear() removes all data for your site, including tokens, preferences, flags.


8. Real-World Use Cases (Good Fits)

✅ Good Uses

  • Theme preference (dark/light)

  • Language selection

  • Auth token (with caution)

  • Feature flags

  • Onboarding completion flag

localStorage.setItem("hasSeenTutorial", "true")

❌ Bad Uses

  • Sensitive data (passwords, secrets)

  • Large datasets

  • Frequently changing data

  • Server state

Local Storage is not a database.


9. Security Considerations (Very Important)

Local Storage is:

  • Accessible by any JavaScript on the page

  • Vulnerable to XSS attacks

⚠️ Avoid storing:

  • Passwords

  • Refresh tokens (prefer HttpOnly cookies)

  • Personally sensitive data

If malicious JS runs on your page, it can read Local Storage.


10. Local Storage in React (Common Pattern)

Read on Initial Render

const [theme, setTheme] = useState(() => {
  return localStorage.getItem("theme") || "light"
})

Sync on Change

useEffect(() => {
  localStorage.setItem("theme", theme)
}, [theme])

🧠 Key idea:

Read once during initialization, write when state changes.


11. Handling Storage Events (Advanced)

Local Storage changes can be observed across tabs.

window.addEventListener("storage", (event) => {
  console.log(event.key, event.newValue)
})

Use this for:

  • Logout across tabs

  • Syncing preferences


12. Best Practices Summary

✔ Always JSON.stringify objects
✔ Always handle missing values
✔ Keep data small and simple
✔ Treat Local Storage as a cache
✔ Never trust it for security
✔ Wrap access in utility functions


Final Mental Model

Local Storage is a persistent string-based cache owned by the browser—not your app.
Use it deliberately, defensively, and sparingly.