Versioning and Upgrades
Migrate schemas with version changes.
Versioning and Upgrades is a free JavaScript Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the JavaScript Academy learning path, and your progress syncs across the web and the CoddyKit app. The JavaScript Academy course includes 4 lessons in total.
Why Versioning?
Apps evolve: you add stores, add indexes, or change how data is shaped. IndexedDB uses a version number to manage these schema changes safely across every user's browser.
The Version Number
The second argument to open is the version, a positive integer. Raising it tells the browser the schema has changed and triggers an upgrade.
// Bumping from 1 to 2 triggers onupgradeneeded:
const request = indexedDB.open('app-db', 2);Upgrade Only Goes Up
You can only increase the version. Opening with a lower number than the stored one fails with an error. Never decrement.
// If the stored DB is version 3:
const req = indexedDB.open('app-db', 2);
req.onerror = () => console.log('cannot open older version');oldVersion and newVersion
Inside onupgradeneeded, the event exposes oldVersion and newVersion. Use them to apply only the migrations that haven't run yet.
request.onupgradeneeded = (e) => {
console.log('upgrading from', e.oldVersion, 'to', e.newVersion);
};Incremental Migrations
A robust pattern is a fall-through using oldVersion: each block builds on the previous so a user on any old version reaches the latest schema.
request.onupgradeneeded = (e) => {
const db = e.target.result;
if (e.oldVersion < 1) {
db.createObjectStore('notes', { keyPath: 'id' });
}
if (e.oldVersion < 2) {
db.createObjectStore('tags', { keyPath: 'name' });
}
};Adding an Index Later
To add an index to an existing store during an upgrade, get the store from the upgrade transaction and call createIndex on it.
request.onupgradeneeded = (e) => {
if (e.oldVersion < 3) {
const store = e.target.transaction.objectStore('notes');
store.createIndex('byDate', 'createdAt');
}
};The Version Change Transaction
During onupgradeneeded, the event's transaction is a special versionchange transaction. It is the only context where schema edits and data migration can both happen.
request.onupgradeneeded = (e) => {
const tx = e.target.transaction; // versionchange tx
const store = tx.objectStore('notes');
// migrate existing records here if needed
};Migrating Existing Data
If a schema change requires reshaping records, iterate the store with a cursor inside the upgrade and put the transformed values back.
const store = e.target.transaction.objectStore('notes');
store.openCursor().onsuccess = (ev) => {
const cursor = ev.target.result;
if (cursor) {
const note = cursor.value;
note.archived = false; // new field
cursor.update(note);
cursor.continue();
}
};The versionchange Event
When one tab upgrades, other tabs holding the old version get a versionchange event on their db. They should close so the upgrade is not blocked.
db.onversionchange = () => {
db.close(); // let the other tab upgrade
console.log('database is outdated, please reload');
};Deleting Stores
You can remove an obsolete store during an upgrade with db.deleteObjectStore(name). This permanently drops it and its data.
request.onupgradeneeded = (e) => {
const db = e.target.result;
if (e.oldVersion < 4 && db.objectStoreNames.contains('temp')) {
db.deleteObjectStore('temp');
}
};Upgrade Best Practices
Keep migrations idempotent and ordered by oldVersion, close old connections on versionchange, and test upgrades from every prior version. This keeps returning users' data intact.
Quick Check
Test your understanding of versioning and upgrades.
Recap
You learned versioning and upgrades:
- Bump the version number to trigger
onupgradeneeded. - Use
oldVersionfor incremental, idempotent migrations. - The upgrade's
versionchangetransaction edits schema and data. - Migrate records with a cursor and
cursor.update. - Close old tabs on the
versionchangeevent.
You finished IndexedDB. Next, Service Workers.
Learn JavaScript with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 59
- Lessons
- 200
Frequently Asked Questions
Is the “Versioning and Upgrades” lesson free?
Yes — any 3 lessons of the JavaScript Academy learning path, including “Versioning and Upgrades”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The JavaScript Academy course includes 4 lessons in total.
What will I learn in “Versioning and Upgrades”?
Migrate schemas with version changes. You practise JavaScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start JavaScript Academy?
No prior experience is required. JavaScript Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.
How long does the “Versioning and Upgrades” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this JavaScript Academy lesson?
Yes. Every JavaScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Opening a Database
- Transactions and CRUD
- Indexes and Queries
- Versioning and Upgrades