Dexie.js — Making IndexedDB Way Less Annoying

HarshalHarshal
3 min read

💬 Wait... What's This?

IndexedDB is a built-in browser feature that lets you store data locally, like for offline support. Sounds great, but it’s a headache to work with. It's full of boilerplate, callbacks, and weird transactions.

If you’re not familiar with IndexedDB or want a refresher, check out my full IndexedDB guide here. It’ll help you understand the basics before we jump into how Dexie.js can simplify it all.

Then I found Dexie.js, and it made everything easier. This post shows how Dexie works and why it's a great solution for managing IndexedDB with TypeScript and React.


🛠️ Installing Dexie

You can get Dexie in two ways:

If you’re using npm:

npm install dexie
npm install --save-dev @types/dexie

Or just drop it into your HTML with a CDN:

<script src="https://cdn.jsdelivr.net/npm/dexie@3.0.3/dist/dexie.js"></script>

📦 Making a Database (Without Losing Your Cool)

With Dexie, setting up a database is simple:

import Dexie from "dexie";

const db = new Dexie("MyDatabase");

db.version(1).stores({
  friends: "++id,name,age"
});
  • new Dexie("MyDatabase"): Names your database.

  • .version(1): Defines the version (you can update it later).

  • .stores(): Creates a "friends" store with fields id, name, and age. The ++id means Dexie auto-increments the id.


✍️ CRUD in Dexie (The Basics)

1. Add Stuff

db.friends.add({ name: "John Doe", age: 30 });

Done! John’s in the database.


2. Read Stuff

db.friends.get(1).then(friend => {
  console.log(friend);
});

Gets the friend with ID 1.


3. Update Stuff

db.friends.update(1, { age: 31 }).then(updated => {
  console.log(updated); // true if successful
});

John’s birthday update.


4. Delete Stuff

db.friends.delete(1);

And now... John’s gone. Sorry, John.


🔍 Searching (Without the Nonsense)

Want to find all friends older than 20?

db.friends.where("age").above(20).toArray().then(friends => {
  console.log(friends);
});

It’s as simple as using Array.filter(), but with Dexie handling the database.


🔄 Transactions (Do Multiple Things at Once)

You can group actions together:

db.transaction('rw', db.friends, () => {
  db.friends.add({ name: "Alice", age: 25 });
  db.friends.add({ name: "Bob", age: 22 });
}).catch(e => {
  console.error("Something went wrong: ", e);
});

If one add fails, none of the actions are saved. It’s all-or-nothing.


🧯 Error Handling (Without Crying)

Dexie uses promises, so you can handle errors using .catch():

db.friends.add({ name: "Charlie", age: 26 }).catch(e => {
  console.error("Oops:", e);
});

No cryptic IndexedDB errors — just regular JavaScript error handling.


🕵️ Fancy Stuff (Indexes and Filters)

Want to find all "John Doe"s?

db.friends.where("name").equals("John Doe").toArray().then(friends => {
  console.log(friends);
});

Want to find all "John Doe"s over 20?

db.friends.where("age").above(20).and(friend => friend.name === "John Doe").toArray().then(friends => {
  console.log(friends);
});

Dexie gives you power with simple, chainable methods.


You can find the full code for this Dexie.js tutorial on my GitHub here.

🧃 Final Thoughts

Dexie.js simplifies working with IndexedDB, making it much more manageable and less error-prone. With Dexie, you get the full power of IndexedDB without the headaches. If you’ve tried IndexedDB and found it too complicated, Dexie is definitely worth a try.

0
Subscribe to my newsletter

Read articles from Harshal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Harshal
Harshal