IndexedDB: The Underrated Powerhouse for Frontend Storage
IndexDB is a browser storage which allows to store large amount of structured data directly in user’s device — and it’s prefect to build offline first web apps.
In simple terms IndexDB is a small offline NoSQL database which can be used to store:
JSON objects
Arrays
Files and Blobs
and prettry much everything that javascript can handle.
So there may be a question how it is different from the local storage. Here is the difference
IndexDB vs LocalStorage
Storage Limit
IndexedDB: ~50MB+ (depends on browser and user disk space)
LocalStorage: ~5MB
Data Type Support
IndexedDB: Stores full JavaScript objects, arrays, blobs, and files directly
LocalStorage: Only string data (objects must be stringified)
Performance
IndexedDB: Faster with large data and supports indexes for quick lookup
LocalStorage: Slower with large data; no indexing
Asynchronous Access
IndexedDB: ✅ Non-blocking, uses promises/events
LocalStorage: ❌ Blocking (synchronous), can affect UI performance
Use Cases
IndexedDB: Best for offline support, storing complex or large data like drafts, form history, app state, etc.
LocalStorage: Good for small flags like
theme
,token
,isFirstVisit
Simple IndexDB Example in Typescript
Open the database
function openDB(dbName: string, storeName: string): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(dbName, 1);
request.onupgradeneeded = () => {
const db = request.result;
if (!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName, { keyPath: "id" });
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
Add data
async function addNote(dbName: string, storeName: string, note: { id: number; title: string }) {
const db = await openDB(dbName, storeName);
const tx = db.transaction(storeName, "readwrite");
const store = tx.objectStore(storeName);
store.add(note);
await tx.complete;
db.close();
}
Read data
async function getAllNotes(dbName: string, storeName: string): Promise<any[]> {
const db = await openDB(dbName, storeName);
const tx = db.transaction(storeName, "readonly");
const store = tx.objectStore(storeName);
return new Promise((resolve, reject) => {
const request = store.getAll();
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
Example Usage
await addNote("NotesDB", "notes", { id: 1, title: "IndexDB is just lit" });
const notes = await getAllNotes("NotesDB", "notes");
console.log(notes); // [{ id: 1, title: "Index Db is just lit" }]
Final Thoughts
IndexedDB is incredibly powerful once you get used to its async nature. It's perfect for storing app data locally — like resume drafts, offline job applications, or even AI-generated content in apps like Resumetweaker 😉