Dexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org.
IndexedDB is the portable database for all browser engines. Dexie.js makes it fun and easy to work with.
But also:
- Dexie.js is widely used by 100,000 of web sites, apps and other projects and supports all browsers, Electron for Desktop apps, Capacitor for iOS / Android apps and of course pure PWAs.
- Dexie.js works around bugs in the IndexedDB implementations, giving a more stable user experience.
- Need sync? Dexie Cloud adds real-time sync, auth, and collaboration on top of Dexie.js β no backend needed.
<!DOCTYPE html>
<html>
<head>
<script type="module">
// Import Dexie
import { Dexie } from 'https://unpkg.com/dexie/dist/modern/dexie.mjs';
//
// Declare Database
//
const db = new Dexie('FriendDatabase');
db.version(1).stores({
friends: '++id, age'
});
//
// Play with it
//
try {
await db.friends.add({ name: 'Alice', age: 21 });
const youngFriends = await db.friends
.where('age')
.below(30)
.toArray();
alert(`My young friends: ${JSON.stringify(youngFriends)}`);
} catch (e) {
alert(`Oops: ${e}`);
}
</script>
</head>
</html>Yes, it's that simple. Read the docs to get into the details.
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/dexie/dist/dexie.js"></script>
<script>
//
// Declare Database
//
const db = new Dexie('FriendDatabase');
db.version(1).stores({
friends: '++id, age'
});
//
// Play with it
//
db.friends.add({ name: 'Alice', age: 21 }).then(() => {
return db.friends
.where('age')
.below(30)
.toArray();
}).then(youngFriends => {
alert (`My young friends: ${JSON.stringify(youngFriends)}`);
}).catch (e => {
alert(`Oops: ${e}`);
});
</script>
</head>
</html>Real-world apps are often built using components in various frameworks. Here's a version of Hello World written for React and Typescript. There are also links below this sample to more tutorials for different frameworks...
import React from 'react';
import { Dexie, type EntityTable } from 'dexie';
import { useLiveQuery } from 'dexie-react-hooks';
// Typing for your entities (hint is to move this to its own module)
export interface Friend {
id: number;
name: string;
age: number;
}
// Database declaration (move this to its own module also)
export const db = new Dexie('FriendDatabase') as Dexie & {
friends: EntityTable<Friend, 'id'>;
};
db.version(1).stores({
friends: '++id, age',
});
// Component:
export function MyDexieReactComponent() {
const youngFriends = useLiveQuery(() =>
db.friends
.where('age')
.below(30)
.toArray()
);
return (
<>
<h3>My young friends</h3>
<ul>
{youngFriends?.map((f) => (
<li key={f.id}>
Name: {f.name}, Age: {f.age}
</li>
))}
</ul>
<button
onClick={() => {
db.friends.add({ name: 'Alice', age: 21 });
}}
>
Add another friend
</button>
</>
);
}Tutorials for React, Svelte, Vue, Angular and vanilla JS
Dexie has kick-ass performance. Its bulk methods take advantage of a lesser-known feature in IndexedDB that makes it possible to store stuff without listening to every onsuccess event. This speeds up the performance to a maximum.
above(key): Collection;
aboveOrEqual(key): Collection;
add(item, key?): Promise;
and(filter: (x) => boolean): Collection;
anyOf(keys[]): Collection;
anyOfIgnoreCase(keys: string[]): Collection;
below(key): Collection;
belowOrEqual(key): Collection;
between(lower, upper, includeLower?, includeUpper?): Collection;
bulkAdd(items: Array): Promise;
bulkDelete(keys: Array): Promise;
bulkPut(items: Array): Promise;
clear(): Promise;
count(): Promise;
delete(key): Promise;
distinct(): Collection;
each(callback: (obj) => any): Promise;
eachKey(callback: (key) => any): Promise;
eachPrimaryKey(callback: (key) => any): Promise;
eachUniqueKey(callback: (key) => any): Promise;
equals(key): Collection;
equalsIgnoreCase(key): Collection;
filter(fn: (obj) => boolean): Collection;
first(): Promise;
get(key): Promise;
inAnyRange(ranges): Collection;
keys(): Promise;
last(): Promise;
limit(n: number): Collection;
modify(changeCallback: (obj: T, ctx:{value: T}) => void): Promise;
modify(changes: { [keyPath: string]: any } ): Promise;
noneOf(keys: Array): Collection;
notEqual(key): Collection;
offset(n: number): Collection;
or(indexOrPrimayKey: string): WhereClause;
orderBy(index: string): Collection;
primaryKeys(): Promise;
put(item: T, key?: Key): Promise;
reverse(): Collection;
sortBy(keyPath: string): Promise;
startsWith(key: string): Collection;
startsWithAnyOf(prefixes: string[]): Collection;
startsWithAnyOfIgnoreCase(prefixes: string[]): Collection;
startsWithIgnoreCase(key: string): Collection;
toArray(): Promise;
toCollection(): Collection;
uniqueKeys(): Promise;
until(filter: (value) => boolean, includeStopEntry?: boolean): Collection;
update(key: Key, changes: { [keyPath: string]: any }): Promise;This is a mix of methods from WhereClause, Table and Collection. Dive into the API reference to see the details.
Dexie Cloud is the easiest way to add sync, authentication, and real-time collaboration to your Dexie app. You keep writing frontend code with Dexie.js β Dexie Cloud handles the rest.
What you get:
- π Sync across devices β changes propagate in real time, no polling needed
- π Authentication β built-in user auth, no identity provider required
- π‘οΈ Access control β share data between users with fine-grained permissions
- π File & blob storage β store attachments alongside your structured data
βοΈ Offline-first β works fully offline, syncs when back online
Getting started is just a few lines:
npm install dexie-cloud-addonimport Dexie from 'dexie';
import dexieCloud from 'dexie-cloud-addon';
const db = new Dexie('MyDatabase', { addons: [dexieCloud] });
db.version(1).stores({ items: '@id, title' });
db.cloud.configure({ databaseUrl: 'https://<your-db>.dexie.cloud' });That's it. Your existing Dexie app now syncs. Hosted cloud or self-hosted on your own infrastructure. π
β Quickstart guide
Sample app:
Source: Dexie Cloud To-do app
Live demo: https://dexie.github.io/Dexie.js/dexie-cloud-todo-app/
β οΈ These packages are legacy and no longer maintained.
If you find references to dexie-observable or dexie-syncable in tutorials, blog posts, or old code, be aware that these are deprecated sync solutions. They are not compatible with Dexie Cloud and should not be used in new projects.
For local-first sync, use dexie-cloud-addon instead. It is the modern, actively maintained solution for offline-first apps with real-time sync.
https://dexie.org/docs/Samples
https://github.com/dexie/Dexie.js/tree/master/samples
https://dexie.org/docs/Questions-and-Answers
npm install dexie
For those who don't like package managers, here's the download links:
https://unpkg.com/dexie@latest/dist/dexie.min.js
https://unpkg.com/dexie@latest/dist/dexie.min.js.map
https://unpkg.com/dexie@latest/dist/modern/dexie.min.mjs
https://unpkg.com/dexie@latest/dist/modern/dexie.min.mjs.map
https://unpkg.com/dexie@latest/dist/dexie.d.ts
See CONTRIBUTING.md
pnpm install
pnpm run build
pnpm test
pnpm run watch