IndexedDB is a low-level browser API for storing large amounts of structured data on the client—including files, blobs, and complex JavaScript objects. As your app evolves, you need to delete outdated records, clear caches, and sometimes remove entire object stores.
This tutorial focuses specifically on deleting data from IndexedDB: removing one record with delete(), wiping a store with clear(), dropping object stores during version upgrades, and handling errors safely.
What You’ll Learn
01
delete()
One record.
02
clear()
All records.
03
readwrite
Tx mode.
04
Upgrade
Drop stores.
05
Confirm UI
Safe deletes.
06
onerror
Handle fail.
Fundamentals
What Is IndexedDB?
IndexedDB is a transactional, key-value database built into modern browsers. Data is organized in object stores (like tables) inside a named database. Each record is a JavaScript object keyed by a keyPath or auto-generated id.
Unlike localStorage, IndexedDB supports indexes, large datasets, and asynchronous operations. It is the recommended client-side storage API for offline-capable web apps, replacing the deprecated Web SQL standard.
💡
Beginner Tip
IndexedDB has three levels of deletion: one record (delete(key)), all records in a store (clear()), and the store itself (deleteObjectStore() during a version upgrade).
Concepts
Understanding Deletion in IndexedDB
Deletion in IndexedDB can mean different things depending on your goal:
Delete one record — remove a single item by its primary key with store.delete(key).
Clear a store — remove every record but keep the object store schema with store.clear().
Delete an object store — remove the entire store (and its indexes) during onupgradeneeded with db.deleteObjectStore(name).
Delete the whole database — wipe everything for your origin with indexedDB.deleteDatabase(name) (advanced; use with care).
Choose the narrowest operation that meets your need. Deleting one cart item is delete(); logging out and wiping local cache might be clear() on several stores.
Core Topic
Deleting Data from IndexedDB
To delete a specific record, open the database, start a readwrite transaction, and call delete() with the record’s key:
js
const request = indexedDB.open('myDatabase', 1);
request.onsuccess = function (event) {
const db = event.target.result;
const tx = db.transaction(['contacts'], 'readwrite');
const store = tx.objectStore('contacts');
const deleteRequest = store.delete(1); /* keyPath id = 1 */
deleteRequest.onsuccess = function () {
console.log('Record deleted successfully');
};
deleteRequest.onerror = function (event) {
console.error('Delete failed:', event.target.error.message);
};
};
request.onerror = function (event) {
console.error('Open failed:', event.target.error.message);
};
The key you pass to delete() must match the store’s keyPath type—a number for id, a string if your keys are strings, and so on.
Bulk Delete
Deleting All Records
When you need to empty an object store without dropping its schema, use clear()—it is faster than deleting keys one by one:
js
const tx = db.transaction(['contacts'], 'readwrite');
const store = tx.objectStore('contacts');
const clearRequest = store.clear();
clearRequest.onsuccess = function () {
console.log('All records removed from contacts store');
};
clearRequest.onerror = function (event) {
console.error('Clear failed:', event.target.error.message);
};
tx.oncomplete = function () {
console.log('Transaction committed');
};
clear() keeps indexes and the store definition intact—only the data rows are removed. Always confirm with the user before clearing large datasets.
Schema
Deleting Object Stores
To remove an entire object store, bump the database version and call deleteObjectStore() inside onupgradeneeded:
js
const request = indexedDB.open('myDatabase', 2); /* version 1 → 2 */
request.onupgradeneeded = function (event) {
const db = event.target.result;
if (db.objectStoreNames.contains('oldStore')) {
db.deleteObjectStore('oldStore');
console.log('Object store removed');
}
};
Version upgrades run for every user who opens the app. Plan migrations carefully—deleting a store destroys all its data permanently for that user.
Reliability
Handling Errors
Handle errors when opening the database, on each delete request, and on the transaction. Use error.message, not legacy errorCode:
js
function deleteContact(db, id) {
return new Promise(function (resolve, reject) {
const tx = db.transaction(['contacts'], 'readwrite');
const delReq = tx.objectStore('contacts').delete(id);
delReq.onsuccess = function () { resolve(); };
delReq.onerror = function () { reject(delReq.error); };
tx.onerror = function () { reject(tx.error); };
});
}
deleteContact(db, 42)
.then(function () { console.log('Deleted id 42'); })
.catch(function (err) { console.error(err.message); });
Note: delete() on a missing key still succeeds—there is no “rows affected” count. Call get(key) first if you need to verify the record existed.
Watch Out
Common Pitfalls
Wrong transaction mode — delete() and clear() require 'readwrite'. A readonly transaction will fail.
Version upgrades — dropping object stores only works in onupgradeneeded with a higher version number.
Silent missing keys — deleting a non-existent key does not throw; confirm existence with get() if your UI needs feedback.
No undo — committed deletes are permanent unless you have a server backup or soft-delete pattern.
clear() is destructive — one call wipes every record in the store; double-check store name and user intent.
Cheat Sheet
⚡ Quick Reference
Operation
Code pattern
Delete one record
store.delete(key)
Clear all records
store.clear()
Delete object store
db.deleteObjectStore(name) in upgrade
Delete entire database
indexedDB.deleteDatabase(name)
Write transaction
db.transaction(['store'], 'readwrite')
Check before delete
store.get(key) then if (result)
One row
delete(key)
By key
All rows
clear()
Empty store
Mode
'readwrite'
Required
Confirm
get(key)
Exists?
Hands-On
Examples Gallery
These examples demonstrate IndexedDB delete patterns. Use Try It Yourself to run live demos in the editor.
📚 Getting Started
Remove a single record by its primary key.
Example 1 — Delete a Record by Key
Remove the contact with id = 1 from the contacts store.
js
const tx = db.transaction(['contacts'], 'readwrite');
const deleteReq = tx.objectStore('contacts').delete(1);
deleteReq.onsuccess = function () {
console.log('Contact id 1 deleted');
};
deleteReq.onerror = function (event) {
console.error('Error:', event.target.error.message);
};
The page seeds id 1 on load. Clicking Delete runs store.delete(1) and updates the status paragraph—no console required.
Applications
🚀 Common Use Cases
Remove cart items — delete one product the user removed from their basket.
Discard drafts — delete unsaved notes or form drafts by id.
Logout cleanup — clear() session or token stores on sign-out.
Cache expiry — delete stale rows older than a timestamp (after querying with a cursor).
Schema migration — drop deprecated object stores during a version upgrade.
🧠 How IndexedDB Delete Works
1
readwrite tx
db.transaction(['store'], 'readwrite')
Open
2
delete(key)
Or clear() for every record in the store.
Remove
3
Commit
Transaction completes; data is gone permanently.
Done
=
🗑️
Record removed
Use get() afterward to confirm the key is gone.
Important
📝 Notes
Deletes require a readwrite transaction on the correct store name.
delete(key) on a missing key succeeds without error—verify with get() if needed.
clear() removes all records but keeps the object store and indexes.
Deletes cannot be undone after the transaction commits.
Confirm destructive actions in your UI before calling clear().
Pair with Retrieve to list records before bulk deletes.
Compatibility
Universal Browser Support
IndexedDB delete(), clear(), and deleteObjectStore() are supported in all modern browsers: Chrome, Firefox, Safari, Edge, and mobile WebViews.
✓ Baseline · Since HTML
IndexedDB delete API
IndexedDB delete(), clear(), and deleteObjectStore() are supported in all modern browsers: Chrome, Firefox, Safari, Edge, and mobile WebViews.
95%Modern browser support
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
IndexedDB delete APIExcellent
Bottom line: Safe to use IndexedDB deletes in production cross-browser web apps.
Pro Tips
💡 Best Practices
✅ Do
Use readwrite for all delete operations
Confirm destructive actions in the UI
Call get(key) when you need “not found” feedback
Use clear() for bulk emptying instead of many deletes
Handle request and transaction onerror callbacks
Plan object-store removal carefully during version upgrades
❌ Don’t
Run deletes in readonly transactions
Call clear() without user confirmation
Assume delete() failed when the key was missing
Drop object stores without a migration plan
Forget that deletes are permanent
Delete stores outside onupgradeneeded
Wrap Up
Conclusion
Deleting data in IndexedDB means calling delete(key) or clear() inside a readwrite transaction, with proper error handling and user confirmation for destructive actions.
For schema-level removal, bump the database version and use deleteObjectStore() in onupgradeneeded. Next, learn how to insert new records into your stores.
Use these points when removing data from a client-side database.
5
Core concepts
🗑️01
delete()
One key.
Basics
💣02
clear()
All rows.
Bulk
🔒03
readwrite
Tx mode.
Required
⚠️04
Permanent
Confirm first.
Safety
🗃️05
Upgrade
Drop store.
Schema
❓ Frequently Asked Questions
Start a readwrite transaction on the object store, then call store.delete(key) with the record's primary key. Example: store.delete(1) removes the record whose keyPath id equals 1.
delete(key) removes one record by its key. clear() removes every record in the object store but keeps the store itself and its indexes. Use clear() for 'empty the table' and delete() for targeting specific items.
Bump the database version in indexedDB.open(name, newVersion) and call db.deleteObjectStore('storeName') inside onupgradeneeded. This is a schema change, not a normal transaction operation.
delete() succeeds silently—there is no error when the key is missing. If you need to warn the user, call get(key) first and check whether result is undefined before deleting.
IndexedDB only allows write operations (delete, clear, put, add) inside readwrite transactions. A readonly transaction cannot modify data.
No. Once the transaction commits, deleted records are gone unless you kept a backup or can re-fetch from a server. Confirm destructive actions in your UI before calling delete() or clear().
Did you know?
indexedDB.deleteDatabase('name') removes an entire database for your origin—all object stores and records at once. Use it for “reset app data” features, but warn users because recovery is impossible without a server backup.