HTML IndexedDB Delete

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples + 3 Try It
delete() / clear() / readwrite

Introduction

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.

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).

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.

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.

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.

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.

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.

Common Pitfalls

  1. Wrong transaction modedelete() and clear() require 'readwrite'. A readonly transaction will fail.
  2. Version upgrades — dropping object stores only works in onupgradeneeded with a higher version number.
  3. Silent missing keys — deleting a non-existent key does not throw; confirm existence with get() if your UI needs feedback.
  4. No undo — committed deletes are permanent unless you have a server backup or soft-delete pattern.
  5. clear() is destructive — one call wipes every record in the store; double-check store name and user intent.

⚡ Quick Reference

OperationCode pattern
Delete one recordstore.delete(key)
Clear all recordsstore.clear()
Delete object storedb.deleteObjectStore(name) in upgrade
Delete entire databaseindexedDB.deleteDatabase(name)
Write transactiondb.transaction(['store'], 'readwrite')
Check before deletestore.get(key) then if (result)
One row
delete(key)

By key

All rows
clear()

Empty store

Mode
'readwrite'

Required

Confirm
get(key)

Exists?

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);
};
Try It Yourself

How It Works

delete(1) targets the record whose keyPath value is 1. The operation runs inside a readwrite transaction and commits when the transaction completes.

Example 2 — Reusable deleteContact Function

Wrap deletes in a function callable from list items, swipe handlers, or trash buttons.

js
function deleteContact(db, id) {
  const tx = db.transaction(['contacts'], 'readwrite');
  const store = tx.objectStore('contacts');

  store.get(id).onsuccess = function (event) {
    if (!event.target.result) {
      console.warn('Contact', id, 'not found');
      return;
    }
    store.delete(id);
  };

  tx.oncomplete = function () {
    console.log('Delete committed for id', id);
  };
}

deleteContact(db, 1);
deleteContact(db, 99); /* not found — warns, no error */
Try It Yourself

How It Works

Checking with get() first lets you warn when id 99 was never stored—because bare delete() would succeed silently.

📈 Practical Patterns

Bulk clear, schema changes, and a complete demo page.

Example 3 — Clear All Records with clear()

Empty the entire items store in one operation—useful for logout or cache reset.

js
function clearAllItems(db) {
  return new Promise(function (resolve, reject) {
    const tx = db.transaction(['items'], 'readwrite');
    const clearReq = tx.objectStore('items').clear();

    clearReq.onsuccess = function () {
      console.log('Store emptied');
    };
    tx.oncomplete = function () { resolve(); };
    tx.onerror = function () { reject(tx.error); };
  });
}

clearAllItems(db).then(function () {
  console.log('Ready for fresh data');
});
Try It Yourself

How It Works

clear() is atomic within the transaction—either all records are removed or the transaction aborts on error.

Example 4 — Delete an Object Store on Upgrade

Remove a deprecated store when migrating from version 1 to version 2.

js
const request = indexedDB.open('myApp', 2);

request.onupgradeneeded = function (event) {
  const db = event.target.result;

  if (db.objectStoreNames.contains('legacyCache')) {
    db.deleteObjectStore('legacyCache');
    console.log('legacyCache store removed');
  }

  if (!db.objectStoreNames.contains('contacts')) {
    db.createObjectStore('contacts', { keyPath: 'id', autoIncrement: true });
  }
};
Try It Yourself

How It Works

Schema changes happen only during version upgrades. Users on version 1 automatically migrate when they load a page that opens version 2.

Example 5 — Example Usage (Complete HTML Page)

A full page that seeds a record and deletes it when the user clicks a button.

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>IndexedDB Delete Example</title>
</head>
<body>
  <h1>IndexedDB Delete Example</h1>
  <button type="button" id="deleteBtn">Delete Record id 1</button>
  <p id="status"></p>

  <script>
    let db;

    const request = indexedDB.open('myDatabase', 1);

    request.onupgradeneeded = function (event) {
      event.target.result.createObjectStore('items', { keyPath: 'id' });
    };

    request.onsuccess = function (event) {
      db = event.target.result;

      const seedTx = db.transaction(['items'], 'readwrite');
      seedTx.objectStore('items').put({ id: 1, value: 'Sample record' });
      seedTx.oncomplete = function () {
        document.getElementById('status').textContent = 'Record ready. Click Delete.';
      };
    };

    document.getElementById('deleteBtn').addEventListener('click', function () {
      const tx = db.transaction(['items'], 'readwrite');
      const delReq = tx.objectStore('items').delete(1);

      delReq.onsuccess = function () {
        document.getElementById('status').textContent =
          'Record id 1 deleted successfully';
      };

      delReq.onerror = function (event) {
        document.getElementById('status').textContent =
          'Error: ' + event.target.error.message;
      };
    });
  </script>
</body>
</html>
Try It Yourself

How It Works

The page seeds id 1 on load. Clicking Delete runs store.delete(1) and updates the status paragraph—no console required.

🚀 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 cleanupclear() 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.

📝 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.

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 Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
IndexedDB delete API Excellent

Bottom line: Safe to use IndexedDB deletes in production cross-browser web apps.

💡 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

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.

Key Takeaways

Knowledge Unlocked

Five things to remember about IndexedDB delete

Use these points when removing data from a client-side database.

5
Core concepts
💣 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.

Practice IndexedDB delete

Seed a contact, click Delete, and see the status update—or try clear() to wipe an entire store.

Open Try It editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful