Dexie 3.2 integrates better with front-end frameworks. Query the db without boilerplate and let your components mirror the database in real time.
Dexie was written to be straightforward and easy to learn. If you've ever had to work with native IndexedDB then you'll certainly appreciate Dexie's concise API.
With only a few lines of extra code, you can build a consistent, authenticated and access controlled local-first app!
/*
|----------------------------|
| Declare your database |
|----------------------------|
*/
const db = new Dexie('MyDatabase');
// Declare tables, IDs and indexes
db.version(1).stores({
friends: '++id, name, age'
});
/*
|-----------------------|
| Then run some queries |
|-----------------------|
*/
// Find some old friends
const oldFriends = await db.friends
.where('age').above(75)
.toArray();
// or make a new one
await db.friends.add({
name: 'Camilla',
age: 25,
street: 'East 13:th Street',
picture: await getBlob('camilla.png')
});
import { useLiveQuery } from "dexie-react-hooks";
import { db } from "./db";
export function FriendList () {
const friends = useLiveQuery(async () => {
//
// Query the DB using our promise based API.
// The end result will magically become
// observable.
//
return await db.friends
.where("age")
.between(18, 65)
.toArray();
});
return <>
<h2>Friends</h2>
<ul>
{
friends?.map(friend =>
<li key={friend.id}>
{friend.name}, {friend.age}
</li>
)
}
</ul>
</>;
}
<script>
import { liveQuery } from "dexie";
import { db } from "./db";
let friends = liveQuery(async () => {
//
// Query the DB using our promise based API.
// The end result will magically become
// observable.
//
return await db.friends
.where("age")
.between(18, 65)
.toArray();
});
</script>
<div>
<h2>Friends</h2>
<ul>
{#each ($friends || []) as friend (friend.id)}
<li>{friend.name}, {friend.age}</li>
{/each}
</ul>
</div>
<template>
<h2>Friends</h2>
<ul>
<li v-for="friend in friends" :key="friend.id">
{{ friend.name }}, {{ friend.age }}
</li>
</ul>
</template>
<script>
import { liveQuery } from "dexie";
import { db } from "../db";
import { useObservable } from "@vueuse/rxjs";
export default {
name: "FriendList",
setup() {
return {
friends: useObservable(
liveQuery(async () => {
//
// Query the DB using our promise based API.
// The end result will magically become
// observable.
//
return await db.friends
.where("age")
.between(18, 65)
.toArray();
})
)
};
}
};
</script>
import { Component } from '@angular/core';
import { liveQuery } from 'dexie';
import { db } from '../db';
@Component({
selector: 'friendlist',
template: `
<h2>Friends</h2>
<ul>
<li *ngFor="let friend of friends$ | async">
{{ friend.name }}, {{ friend.age }}
</li>
</ul>
`
})
export class FriendsComponent {
friends$ = liveQuery(() => listFriends());
}
async function listFriends() {
//
// Query the DB using our promise based API.
// The end result will magically become
// observable.
//
return await db.friends
.where("age")
.between(18, 65)
.toArray();
}
Turn on sync with a few simple steps:
npx dexie-cloud create
npx dexie-cloud whitelist http://localhost:3000
npm install dexie@latest
npm install dexie-cloud-addon
import Dexie from "dexie";
import dexieCloud from "dexie-cloud-addon";
const db = new Dexie('MySyncedDB', {addons: [dexieCloud]});
db.version(1).stores({
friends: '++id, name, age' // '++' = auto-incremented ID
friends: '@id, name, age' // '@' = auto-generated global ID
});
db.cloud.configure({
databaseUrl: "https://<yourdatabase>.dexie.cloud",
requireAuth: true // (optional. Block DB until authenticated)
});
Read more about authentication, access control and consistency in the Dexie Cloud documentation.
Now go make something awesome.