IndexedDB
debt(d7/e5/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). Lighthouse can flag localStorage misuse for large data, but detecting IndexedDB quota errors, missing backend sync, or async blocking patterns requires runtime testing or manual inspection. Static detection is minimal; the common_mistakes (storage quota errors, missing sync) only surface under production load or deliberate offline testing.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix (migrate to idb library + add backend sync) is not a one-line swap—it requires refactoring the storage layer AND adding sync logic that may touch form handlers, API calls, and error handling across the component. If IndexedDB is already deeply integrated without sync, rewiring to treat it as cache and ensure PHP backend consistency touches multiple files.
Closest to 'persistent productivity tax' (b5). IndexedDB choice affects all offline-capable features in a web app—any form, cached content fetch, or pending action must now consider IndexedDB state, quota limits, and sync timing. It's not load-bearing (you can work around it), but every data-persistence decision going forward must account for quota pressure, browser eviction, and backend sync strategy. This slows down multiple work streams that touch offline data.
Closest to 'serious trap' (t7). The core misconception—that IndexedDB is persistent like a server database—directly contradicts localStorage and contradicts how devs expect 'database' to behave. The canonical trap is that the browser can silently clear IndexedDB under storage pressure, making it unsafe as a source of truth. Developers accustomed to server DBs will assume data persists; the async-only API is also a secondary gotcha compared to the synchronous-looking localStorage they may have used before.
Also Known As
TL;DR
Explanation
IndexedDB is a transactional object store persisted in the browser. Stores JS objects including Blobs. Indexed for efficient querying. Works offline (alongside Service Workers). Used for: offline drafts before sync to PHP, caching API responses, large client-side datasets. API is callback/promise-based (use idb library for cleaner async). Quota: typically hundreds of MB. Cleared by browser in storage pressure. Not accessible cross-origin.
Common Misconception
Why It Matters
Common Mistakes
- Not handling storage quota errors
- Not syncing to PHP backend — treating IndexedDB as the source of truth
- Using raw IndexedDB API instead of idb library
- Blocking UI with synchronous-looking patterns (it's async)
Code Examples
// Raw API — verbose and error-prone:
const req = indexedDB.open('app', 1);
req.onupgradeneeded = e => e.target.result.createObjectStore('drafts');
req.onsuccess = e => {
const db = e.target.result; // nested callbacks...
};
// idb library — clean async/await:
import { openDB } from 'idb';
const db = await openDB('app', 1, {
upgrade(db) { db.createObjectStore('drafts', { keyPath: 'id' }); }
});
// Save draft locally:
await db.put('drafts', { id: 'post-1', content: editor.value, savedAt: Date.now() });
// Sync to PHP when online:
navigator.onLine && await fetch('/api/drafts', { method:'POST', body: JSON.stringify(draft) });