DEV Community

Cover image for Stop Using `localStorage` for Everything – Here's What to Use Instead
Menula De Silva
Menula De Silva

Posted on

Stop Using `localStorage` for Everything – Here's What to Use Instead

Stop Using localStorage for Everything – Here's What to Use Instead

⚠️ Warning: localStorage is NOT a secure place to store sensitive data. Yet, it’s used everywhere. Let’s fix that with better alternatives.


😰 The Problem: localStorage is Like a Digital Trash Can

localStorage is tempting: it’s fast, globally accessible, and requires no setup. But it has serious flaws:

  • No encryption: Data is stored in plain text.
  • Vulnerable to XSS attacks: Malicious scripts can access it.
  • Synchronous: Blocks the main thread, slowing down your app.
  • No expiration: Data persists indefinitely unless manually cleared.
  • Poor for structured data: It’s just key-value pairs.

Why are you like this?


🧠 Smarter Alternatives to localStorage

Here’s a quick guide to better storage options based on your use case:

Use Case Better Alternative
Temporary session data sessionStorage
Authentication tokens HttpOnly Cookies
Structured or large data IndexedDB or Dexie.js
Offline support & assets Cache API + Service Workers
Relational browser database SQLite with WebAssembly (e.g., sql.js)

Let’s dive into each option with examples.


🧪 1. sessionStorage: Perfect for Tab-Specific Data

sessionStorage stores data only for the duration of a browser tab’s session. Once the tab closes, the data is gone.

// Save a theme preference sessionStorage.setItem("theme", "dark"); // Retrieve it console.log(sessionStorage.getItem("theme")); // "dark" 
Enter fullscreen mode Exit fullscreen mode

Pros:

  • ✅ Isolated to the current tab (no cross-tab interference).
  • ✅ Simple API, similar to localStorage.

Cons:

  • ❌ Data is cleared when the tab closes.

Use Case: Store temporary UI state, like form inputs or tab-specific settings.


📦 2. IndexedDB (or Dexie.js): Scalable, Async, and Structured

IndexedDB is a powerful, asynchronous NoSQL database in the browser, perfect for complex or large datasets. For a simpler API, use Dexie.js, a wrapper around IndexedDB.

🔹 Example with Dexie.js

import Dexie from "dexie"; // Initialize database const db = new Dexie("MyAppDB"); db.version(1).stores({ users: "++id, name, age" // Auto-incrementing ID, indexed fields }); // Add a user await db.users.add({ name: "Menula", age: 12 }); // Query users const youngUsers = await db.users.where("age").below(18).toArray(); console.log(youngUsers); // [{ id: 1, name: "Menula", age: 12 }] 
Enter fullscreen mode Exit fullscreen mode

Pros:

  • ✅ Asynchronous, non-blocking.
  • ✅ Supports complex queries and large datasets (100MB+).
  • ✅ Structured data with indexing.

Cons:

  • ❌ Steeper learning curve than localStorage.

Use Case: Storing user profiles, app state, or large datasets.

Dexie.js in action


🔐 3. HttpOnly Cookies: Secure Authentication

Never store auth tokens in localStorage! Why? Because any malicious JavaScript can read it:

// Hacker script console.log(localStorage.getItem("auth_token")); // 😱 Steals your token! 
Enter fullscreen mode Exit fullscreen mode

Instead, use HttpOnly Cookies, which are inaccessible to JavaScript.

Example (Server-Side):

Set-Cookie: token=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600 
Enter fullscreen mode Exit fullscreen mode

Pros:

  • ✅ Invisible to JavaScript, reducing XSS risks.
  • ✅ Automatically sent with HTTP requests.
  • ✅ Configurable expiration.

Cons:

  • ❌ Limited to 4KB per cookie.
  • ❌ Requires server-side setup.

Use Case: Securely storing authentication tokens or session IDs.


🚀 4. Cache API: Offline Support & Performance

The Cache API, paired with Service Workers, is ideal for caching assets or data for offline-first apps or Progressive Web Apps (PWAs).

// Register a Service Worker navigator.serviceWorker.register("/sw.js"); // Cache assets caches.open("app-cache").then(cache => { cache.addAll(["/styles.css", "/script.js"]); }); 
Enter fullscreen mode Exit fullscreen mode

Pros:

  • ✅ Enables offline functionality.
  • ✅ Fast asset retrieval.
  • ✅ Great for PWAs.

Cons:

  • ❌ Requires Service Worker setup.
  • ❌ Complex for dynamic data.

Use Case: Caching images, scripts, or API responses for offline access.


🧩 5. SQLite in the Browser: Real SQL Power

With sql.js, you can run a full SQLite database in the browser using WebAssembly.

import initSqlJs from "sql.js"; // Initialize SQLite const SQL = await initSqlJs(); const db = new SQL.Database(); // Create and populate a table db.run("CREATE TABLE test (col1, col2);"); db.run("INSERT INTO test VALUES (?, ?);", [1, "hello"]); // Query data const results = db.exec("SELECT * FROM test"); console.log(results); // [{ col1: 1, col2: "hello" }] 
Enter fullscreen mode Exit fullscreen mode

Pros:

  • ✅ Full SQL capabilities.
  • ✅ Great for relational data.
  • ✅ Large storage capacity.

Cons:

  • ❌ Requires WebAssembly setup.
  • ❌ Overhead for simple use cases.

Use Case: Complex apps needing relational data, like dashboards or CRMs.


✅ When is localStorage Actually OK?

localStorage isn’t evil—it’s just overused. It’s fine for:

  • UI Preferences: E.g., saving a user’s theme choice ("dark" or "light").
  • Feature Toggles: E.g., enabling/disabling experimental features.
  • Non-Sensitive Metadata: E.g., public app settings.
// Safe use of localStorage localStorage.setItem("theme", "dark"); localStorage.setItem("feature:beta", "true"); 
Enter fullscreen mode Exit fullscreen mode

🎯 Storage Options Compared

Feature localStorage sessionStorage IndexedDB HttpOnly Cookies Cache API
Persistent
Secure
Structured Data
Capacity ~5MB ~5MB 100MB+ <4KB Unlimited
Async

🔍 Visual Summary

Browser storage comparison

Credit: Inspired by LogRocket Blog.


👋 Final Thoughts

Stop defaulting to localStorage for everything. Instead, choose the right tool based on:

  • 📌 Security: Prioritize HttpOnly Cookies for auth.
  • 📌 Data Complexity: Use IndexedDB or SQLite for structured data.
  • 📌 Performance: Leverage Cache API for offline assets.

Let’s build safer, faster, and smarter web apps! 🚀


💬 What’s Your Go-To Storage Solution?

Do you love IndexedDB? Swear by HttpOnly Cookies? Or have you found a niche use for sql.js? Share your favorite tools and tricks in the comments below! 👇


❤️ Support This Post

If you found this helpful, drop a ❤️, 🦄, or 📝 on Dev.to to keep the knowledge sharing going!

Top comments (0)