IndexedDB update means replacing a stored record with a new value for the same primary key. The main API is IDBObjectStore.put(). It inserts if the key is new and replaces if it already exists.
put() stores the whole object you pass—it does not merge fields. For a one-field change, get first, edit in JavaScript, then put() again. While iterating, prefer IDBCursor.update(). Pair with insert and delete as needed.
Baseline · Widely available.
Not deprecated. put() and cursor update() have been stable across browsers since about July 2015. Also available in Web Workers.
Quick rule.
Saving a form that may already exist? Use put(). Must fail on duplicates? Use add(). Must change only existing rows? get() first, then put() only if found.
Syntax
Syntax
syntax.js
store.put(value, key?)
syntax.js
cursor.update(value)
With an in-line keyPath, keep the key on the object (for example { id: 1, name: "Alex" }). Both calls need a readwrite transaction.
Reference
Parameters
Parameter
Method
Description
value
put, cursor.update
The full record to store. Must be structured-cloneable. Replaces the previous value for that key.
key
put (optional)
Out-of-line primary key when the store has no in-line keyPath / generator. Omit for in-line or autoIncrement keys.
Result
Return Value
Both return an IDBRequest. On success, request.result is the key of the stored record. Prefer also listening to transaction.oncomplete when you need confirmation the write committed.
Exception
When it is thrown
ReadOnlyError
Transaction mode is readonly
DataError
Invalid or mismatched key / keyPath rules
DataCloneError
Value cannot be structured-cloned
TransactionInactiveError
The transaction is no longer active
InvalidStateError
Store deleted, or cursor cannot update (e.g. key cursor)
Flow
How It Works
A safe partial update follows these steps:
Open a write tx: db.transaction(['store'], 'readwrite').
Read with get(key) in that same transaction.
Change fields on the returned object in JavaScript.
Write back with put(object) (or cursor.update() when iterating).
Handle success or error; wait for oncomplete when needed.
Most update bugs come from treating put() like a field merge or using the wrong transaction mode.
replace
put() replaces the whole value
Omitting fields drops them. Use get-modify-put when you need a partial change.
upsert
Missing keys get created
put() inserts when the key is absent. Check with get() if you only want updates.
mode
Need readwrite
put() and cursor.update() throw ReadOnlyError in a readonly transaction.
cursor
Key cursors cannot update
openKeyCursor() does not support update(). Use openCursor() instead.
clone
Values must be cloneable
Functions and DOM nodes throw DataCloneError. Prefer plain objects.
Compatibility
Browser Support
IndexedDB put() and IDBCursor.update() are standard Web Storage features in modern browsers—not a Node.js, Deno, or Bun API.
✓ Baseline · Widely available
IndexedDB put()
Widely available since about July 2015. Chrome, Firefox, Safari, Edge, and Opera support put() and cursor update() for object-store writes.
96%Global support (approx.)
Google Chrome24+
Full support
Mozilla Firefox16+
Full support
Apple Safari10+
Full support
Microsoft Edge12+
Full support
Opera15+
Full support
Samsung Internet1.5+
Full support
Internet Explorer10+
Partial / older
IndexedDB put()Widely supported
Bottom line: Safe to use IndexedDB updates in production web apps. Prefer feature detection with window.indexedDB for very old browsers.
Remember
Key Takeaways
Main API:store.put(value) inserts or replaces by primary key.
Partial change: get → modify object → put, in one readwrite transaction.
No merge: omitted fields are removed when you put a thinner object.
While iterating: prefer cursor.update(value) over a separate key lookup.
One line: update with put() (full replace) or get-modify-put inside readwrite.
Frequently Asked Questions
Start a readwrite transaction, then call store.put(object) with the same primary key and new field values. put() replaces the entire stored record. For a partial change, get(key) first, modify the object in JavaScript, then put() it back in the same transaction.
put() inserts or replaces by key (upsert). add() only inserts and fails with ConstraintError if the key already exists. Use put() when you intend to change existing data.
Only if you already have the full object in memory. put() does not merge fields—it stores exactly what you pass. To change one property while keeping others, get() the record, change that property, then put() the complete object.
put() creates the record. That is an upsert. If you only want to update existing rows, call get() first and skip put() when result is undefined.
IndexedDB requires readwrite mode for put() and cursor.update(). readonly transactions cannot modify data. Keep get() and put() in the same transaction so the read and write stay consistent.
While iterating with openCursor(), cursor.update(newValue) updates the current row without looking up the key again. Prefer it over a separate put() when you already have a cursor on the record.