Convert Figma logo to code with AI

dexie logoDexie.js

A Minimalistic Wrapper for IndexedDB

11,406
640
11,406
564

Top Related Projects

💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

21,334

Simple and fast JSON database

16,717

:kangaroo: - PouchDB is a pocket-sized database.

21,127

A fast, local first, reactive Database for JavaScript Applications https://rxdb.info/

:nut_and_bolt: A relentless key-value store for the browser.

The fastest and simplest library for SQLite3 in Node.js.

Quick Overview

Dexie.js is a minimalistic wrapper for IndexedDB, providing a clean and simple API for working with client-side databases in web applications. It offers a powerful yet easy-to-use interface for storing and retrieving JavaScript objects, making it an excellent choice for offline-capable web apps.

Pros

  • Simple and intuitive API, reducing the complexity of working with IndexedDB
  • Supports complex querying and indexing capabilities
  • Offers robust error handling and transaction management
  • Lightweight and fast, with minimal overhead

Cons

  • Limited browser support for older versions (IE10 and below)
  • May require additional setup for optimal performance in large-scale applications
  • Learning curve for developers unfamiliar with IndexedDB concepts
  • Some advanced IndexedDB features may not be directly exposed

Code Examples

  1. Creating a database and defining object stores:
const db = new Dexie('MyDatabase');
db.version(1).stores({
  friends: '++id, name, age',
  pets: '++id, name, species'
});
  1. Adding items to the database:
await db.friends.add({ name: 'John', age: 30 });
await db.pets.add({ name: 'Fluffy', species: 'cat' });
  1. Querying the database:
const youngFriends = await db.friends.where('age').below(25).toArray();
const cats = await db.pets.where('species').equals('cat').toArray();
  1. Updating records:
await db.friends.update(1, { age: 31 });
await db.pets.where('species').equals('dog').modify({ species: 'canine' });

Getting Started

  1. Install Dexie.js:
npm install dexie
  1. Import and use Dexie in your project:
import Dexie from 'dexie';

const db = new Dexie('MyDatabase');
db.version(1).stores({
  items: '++id, name, category'
});

// Open the database
db.open()
  .then(() => console.log('Database opened successfully'))
  .catch(err => console.error('Error opening database:', err));

// Use the database
async function addItem(name, category) {
  try {
    const id = await db.items.add({ name, category });
    console.log(`Item added with id ${id}`);
  } catch (error) {
    console.error('Error adding item:', error);
  }
}

addItem('Example Item', 'Test Category');

This quick start guide demonstrates how to create a database, define an object store, open the database, and perform a basic operation (adding an item).

Competitor Comparisons

💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

Pros of localForage

  • Simple API with a key-value store interface, making it easy to use for developers familiar with localStorage
  • Automatic selection of the best available storage mechanism (IndexedDB, WebSQL, or localStorage)
  • Built-in support for multiple storage drivers and easy driver customization

Cons of localForage

  • Limited querying capabilities compared to Dexie.js
  • Lack of advanced features like indexing and complex data structures
  • May have slightly lower performance for large datasets or complex operations

Code Comparison

localForage:

localforage.setItem('key', 'value').then(function() {
  return localforage.getItem('key');
}).then(function(value) {
  console.log(value);
}).catch(function(err) {
  console.log(err);
});

Dexie.js:

db.friends.add({name: 'John', age: 30}).then(function() {
  return db.friends.where('age').above(25).toArray();
}).then(function(friends) {
  console.log(friends);
}).catch(function(error) {
  console.error(error);
});

Summary

localForage offers a simpler API and automatic storage mechanism selection, making it ideal for basic storage needs. However, Dexie.js provides more advanced features and better performance for complex data operations, making it suitable for larger applications with sophisticated data management requirements.

21,334

Simple and fast JSON database

Pros of lowdb

  • Simpler API and easier to set up for small projects
  • Supports JSON file-based storage out of the box
  • Lightweight with minimal dependencies

Cons of lowdb

  • Limited scalability for large datasets
  • Lacks advanced querying capabilities
  • No built-in support for complex data types or indexing

Code Comparison

lowdb:

const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')

const adapter = new FileSync('db.json')
const db = low(adapter)

db.defaults({ posts: [] }).write()
db.get('posts').push({ id: 1, title: 'lowdb is easy' }).write()

Dexie.js:

const db = new Dexie('MyDatabase')
db.version(1).stores({
  posts: '++id, title'
})

db.posts.add({ title: 'Dexie is powerful' })
  .then(() => db.posts.where('title').equals('Dexie is powerful').toArray())
  .then(posts => console.log(posts))

Summary

lowdb is ideal for small projects requiring simple JSON storage, while Dexie.js offers more robust features for larger applications needing advanced querying and indexing capabilities. lowdb's simplicity comes at the cost of scalability, whereas Dexie.js provides a more comprehensive solution for complex data management needs.

16,717

:kangaroo: - PouchDB is a pocket-sized database.

Pros of PouchDB

  • Synchronization capabilities with CouchDB and other PouchDB instances
  • Built-in support for offline-first applications
  • Extensive ecosystem and plugin support

Cons of PouchDB

  • Larger file size and potentially slower performance for simple use cases
  • More complex API compared to Dexie.js
  • Steeper learning curve, especially for developers new to NoSQL databases

Code Comparison

Dexie.js:

const db = new Dexie('MyDatabase');
db.version(1).stores({
  friends: '++id, name, age'
});

await db.friends.add({ name: 'John', age: 30 });
const john = await db.friends.where('name').equals('John').first();

PouchDB:

const db = new PouchDB('MyDatabase');

await db.put({ _id: 'john', name: 'John', age: 30 });
const result = await db.find({
  selector: { name: 'John' }
});
const john = result.docs[0];

Both libraries provide easy-to-use APIs for working with IndexedDB, but PouchDB offers more advanced features like synchronization at the cost of increased complexity. Dexie.js focuses on simplicity and performance for basic IndexedDB operations, while PouchDB is better suited for applications requiring offline support and data syncing across multiple devices or servers.

21,127

A fast, local first, reactive Database for JavaScript Applications https://rxdb.info/

Pros of RxDB

  • Real-time synchronization and conflict resolution
  • Built-in support for reactive programming using RxJS
  • Advanced querying capabilities, including mango queries

Cons of RxDB

  • Steeper learning curve, especially for developers unfamiliar with RxJS
  • Larger bundle size due to additional features and dependencies

Code Comparison

RxDB:

const db = await createRxDatabase({
  name: 'heroesdb',
  adapter: 'idb'
});

const heroesCollection = await db.addCollections({
  heroes: {
    schema: mySchema
  }
});

const subscription = heroesCollection.heroes
  .find()
  .$.subscribe(heroes => console.log('heroes:', heroes));

Dexie.js:

const db = new Dexie('heroesdb');
db.version(1).stores({
  heroes: '++id, name, power'
});

db.heroes.toArray().then(heroes => console.log('heroes:', heroes));

RxDB offers a more reactive approach with real-time updates, while Dexie.js provides a simpler API for basic IndexedDB operations. RxDB's code involves setting up a database, adding collections, and subscribing to changes. Dexie.js focuses on defining a schema and performing queries. The choice between the two depends on the specific needs of your project, with RxDB being more suitable for complex, real-time applications, and Dexie.js for simpler, straightforward IndexedDB usage.

:nut_and_bolt: A relentless key-value store for the browser.

Pros of ImmortalDB

  • Simpler API with a focus on key-value storage
  • Built-in support for multiple storage backends (LocalStorage, IndexedDB, Cookies)
  • Automatic fallback mechanism for better cross-browser compatibility

Cons of ImmortalDB

  • Limited querying capabilities compared to Dexie.js
  • Lacks advanced features like indexing and complex data structures
  • Smaller community and fewer resources available

Code Comparison

ImmortalDB:

import ImmortalDB from 'immortal-db';

await ImmortalDB.set('key', 'value');
const value = await ImmortalDB.get('key');

Dexie.js:

import Dexie from 'dexie';

const db = new Dexie('MyDatabase');
db.version(1).stores({ items: '++id, name, category' });

await db.items.add({ name: 'Item', category: 'Category' });
const items = await db.items.where('category').equals('Category').toArray();

ImmortalDB provides a straightforward key-value storage solution with built-in support for multiple storage backends, making it easier to use for simple storage needs. However, it lacks the advanced querying and indexing capabilities of Dexie.js.

Dexie.js offers a more powerful and flexible solution for complex data storage and retrieval, with support for indexing, advanced querying, and complex data structures. It's better suited for applications requiring sophisticated data management but may have a steeper learning curve compared to ImmortalDB.

The fastest and simplest library for SQLite3 in Node.js.

Pros of better-sqlite3

  • Native C++ SQLite3 binding, offering superior performance for Node.js applications
  • Synchronous API, simplifying code structure and reducing callback complexity
  • Full support for prepared statements, enhancing query efficiency and security

Cons of better-sqlite3

  • Limited to Node.js environments, not suitable for browser-based applications
  • Requires compilation of native modules, which can complicate deployment
  • Steeper learning curve for developers unfamiliar with SQLite syntax

Code Comparison

better-sqlite3:

const db = new Database('foobar.db');
const stmt = db.prepare('INSERT INTO users VALUES (?, ?)');
const info = stmt.run('John Doe', 35);

Dexie.js:

const db = new Dexie('MyDatabase');
db.version(1).stores({ users: '++id, name, age' });
await db.users.add({ name: 'John Doe', age: 35 });

better-sqlite3 provides a more traditional SQL approach, while Dexie.js offers an object-oriented interface for IndexedDB. The choice between them depends on the specific requirements of your project, such as the target environment (Node.js vs. browser) and the preferred database paradigm.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Dexie.js

NPM Version Build Status

Dexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org.

Why Dexie.js?

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.
  • It's an easy step to make it sync.

Hello World

<!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>

Yes, it's that simple. Read the docs to get into the details.

Hello World (for modern browsers)

All modern browsers support ES modules and top-level awaits. No transipler needed. Here's the previous example in a modern flavour:

<!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>

Hello World (React + Typescript)

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

API Reference

Samples

Performance

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.

Supported operations

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

Dexie Cloud is a commercial offering that can be used as an add-on to Dexie.js. It syncs a Dexie database with a server and enables developers to build apps without having to care about backend or database layer else than the frontend code with Dexie.js as the sole database layer.

Source for a sample Dexie Cloud app: Dexie Cloud To-do app

See the sample Dexie Cloud app in action: https://dexie.github.io/Dexie.js/dexie-cloud-todo-app/

Samples

https://dexie.org/docs/Samples

https://github.com/dexie/Dexie.js/tree/master/samples

Knowledge Base

https://dexie.org/docs/Questions-and-Answers

Website

https://dexie.org

Install via npm

npm install dexie

Download

For those who don't like package managers, here's the download links:

UMD (for legacy script includes as well as commonjs require):

https://unpkg.com/dexie@latest/dist/dexie.min.js

https://unpkg.com/dexie@latest/dist/dexie.min.js.map

Modern (ES module):

https://unpkg.com/dexie@latest/dist/modern/dexie.min.mjs

https://unpkg.com/dexie@latest/dist/modern/dexie.min.mjs.map

Typings:

https://unpkg.com/dexie@latest/dist/dexie.d.ts

Contributing

See CONTRIBUTING.md

Build

pnpm install
pnpm run build

Test

pnpm test

Watch

pnpm run watch

Browser testing via LAMDBATEST

NPM DownloadsLast 30 Days