Detailed explanation
IndexedDB is a low-level, transactional database built into browsers for storing substantial amounts of structured data on the client. It is useful for offline-first applications, locally saved drafts, cached application records, and queues of changes that must be synchronised with a server later. It can store JavaScript values supported by the structured clone algorithm, including objects, arrays, files, and blobs. Although often grouped with HTML/CSS interview topics, IndexedDB is a browser API accessed through JavaScript, not an HTML element or CSS feature.
Data is organised into named databases containing object stores, which are roughly comparable to tables but do not require every record to share the same fields. Each record has a primary key, supplied explicitly, generated automatically, or extracted from a property through a key path. In the example, indexedDB.open('MyDB', 1) opens database version 1 or creates it if needed. The onupgradeneeded handler runs for initial creation or a version increase; createObjectStore('notes', { keyPath: 'id' }) creates a store whose records use their id property as the key. Object stores and indexes must be created or changed within this version-change transaction.
Reads and writes run inside transactions scoped to specific object stores. Transactions provide atomicity: either their changes commit together or they are rolled back on failure. The native API is asynchronous and uses requests and events, avoiding synchronous storage operations on the main thread. Applications retrieve records by key, use indexes to look up other properties, or iterate through key ranges with cursors. IndexedDB does not provide SQL or arbitrary relational joins, so query requirements should guide index design. A successful write request alone does not confirm that the entire transaction has committed; the transaction's complete event does.
Compared with localStorage, IndexedDB supports richer values, indexed access, transactions, and generally larger browser-managed storage allowances. However, quotas vary, writes can fail, and data may be evicted or cleared by the user. It is therefore not automatically a durable backup or a replacement for server storage. Interviewers usually look for this practical distinction: choose IndexedDB for sizeable, structured, asynchronous local persistence, while using localStorage only for small, simple string-based settings.
Key points to remember
- Use IndexedDB for offline records, drafts, blobs, and pending synchronisation data.
- Store structured-clone-compatible values in object stores identified by primary keys.
- Use indexes and key ranges for efficient lookups; IndexedDB is not a SQL database.
- Perform reads and writes asynchronously within transactions, and confirm writes through transaction completion.
- Handle schema upgrades, storage limits, errors, and possible data loss explicitly.
Common mistakes candidates make
- Describing IndexedDB as synchronous string-only storage like localStorage.
- Creating object stores outside an upgrade transaction or assuming indexes support arbitrary queries.
- Assuming stored data is permanent, automatically synchronised with a server, or committed when an individual request succeeds.
Likely follow-up questions
How would you add a note after opening the database?
In the open request's success handler, obtain request.result, create db.transaction('notes', 'readwrite'), and call transaction.objectStore('notes').add({ id: 1, text: 'Revise IndexedDB' }). Handle transaction completion and failure; add rejects duplicate primary keys, whereas put can insert or replace a record.
How do you change an existing IndexedDB schema?
Open the database with a higher integer version and perform schema changes in onupgradeneeded. Other tabs holding older connections can block the upgrade, so handle versionchange by closing those connections and handle the open request's blocked event.
How is IndexedDB different from the Cache API?
IndexedDB stores structured application data with keys, indexes, and transactions. The Cache API stores Request/Response pairs and is commonly used with service workers to serve cached resources; an offline application may use both.
Interview tip: Start with its purpose, give an offline-app example, then contrast its structured storage, indexes, and transactions with localStorage.
