Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Well-tested, low-level wrapper around the IndexedDB API. It can sync, too.

See test.js for examples.


$ yarn add azer/indexeddb # or npm i azer/indexeddb



Define a store for each data type. Stores will have following methods;

const db = require('indexeddb')('mydb', {
    version: 1

// Create your stores before opening the connection
const people ='people', {
    key: 'email', // you can choose custom key optionally by: "key: { autoIncrement: true, keyPath: 'id' }"
    indexes: [
      { name: 'email', options: { unique: true } },


Store method to add documents.

Parameters: store.add(document, callback)

people.add({ name: 'foo', email: '' }, error => console.log(error))


Store method to iterate all documents in the store.

people.all((err, row) => {
  if (err) return console.error(err)

  if (row) {


Store method to get a document by key value.

Parameters: store.get(key, callback)

people.get(1, (error, result) => console.log(error, result))


Store method to get document(s) matching given index key and value.

Parameters: store.getByIndex(indexName, indexValue, callback)

people.getByIndex('email', '' }, (error, result) => console.log(error, result))


Store method to get document(s) selecting by index, range and/or expected values.

Parameters:, rangeOptions, direction <optional>, callback)

Range options can be expected values or have an object with following properties;

  • from
  • to
  • only'name', { from: 'a', to: 'e' }, (error, row) => {
    console.log(error, result)

You can optionally choose direction parameter for getting results sorted. Direction paramters are:

  • prev (descending)
  • next (ascending)'name', { from: 'a', to: 'e' }, 'prev', (error, row) => {
    console.log(error, result)

Direction parameters can be useful when you need to iterate by a numeric field. For example, we can iterate the people store by age in descending order:'age', null, 'prev', (error, row) => {
    console.log(error, result)

Range options can be field keys, too. You can select by matching multiple fields at a time. Make sure having an index for the combination of the indexes though;

const people ='people', {
    key: { autoIncrement: true, keyPath: 'id' },
    indexes: [
        { name: 'age+country', fields: ['age', 'country'] }

Now we can select people by age and country:'age+country', [20, 'jamaika'], (error, row) => {
    console.log(error, result)

from and to options provides us more flexibility here:'age+country', { from: [20, 'jamaika'], to: [30, 'jamaika'] }, (error, result) => {
    console.log(error, result)


Store method to update a document.

Parameters: store.update(document, callback)

people.update({ id: 1, name: 'foo', email: '' }, error => console.log(error))


Store method to delete a record.

Parameters: store.delete(id, callback)

people.delete(1, error => console.log(error))


Store method to count all records.

people.count(error, count => console.log(error, count))


Store option to perform upgrade when there is a version change. It's an optional method.

const people ='people', {
    key: { autoIncrement: true, keyPath: 'id' },
    upgrade: upgrade

function upgrade () {
  people.createIndex('name', { unique: false })


This is an optimized pubsub object where you can subscribe for changes. Here is an example;

people.onChange(() => console.log('people store has changed'))

You can subscribe for once, too;

people.onChange.once(() => console.log('he-yo!'))

There is unsubscribe methods, as well. See full API reference for this particular object at pubsub repository.


If callback is not passed, a Promise will be returned. Here is an example;

const rows = [{ name: 'foo' }, { name: 'bar' }, { name: 'qux' }]

Promise.all( => people.add(row))

Supported methods:

  • add
  • get
  • getByIndex
  • update
  • delete



You can use the sync method to keep multiple local indexeddb database instances easily.

const a = require('indexeddb')('local', {
  version: 1

const b = require('indexeddb')('local', {
  version: 1

const c = require('indexeddb')('local', {
  version: 1


That's it! Now all three local databases will be in sync automatically.


You can sync your IndexedDB remotely. To accomplish this, you'll need to customize Push and Pull classes. Both of these classes pass eachother update objects. Here is an example update object;

  action: 'add',
  store: 'articles',
  id: 1,
  doc: {
    title: 'hello world',
    content: 'lorem ipsum ...'

Customizing Push

The Push class takes updates from itself and sends them to the target. If we are syncing an IndexedDB instance with a remote API, then we'll tweak this class to take updates from the API and simply pass it to the publish method.

const Push = require('indexeddb/lib/push')

class PushFromAPI extends Push {
  constructor() {

  checkForUpdates() {
    myapi.get("/sync", resp => {
      setTimeout(() => this.checkForUpdates(), 1000) // keep checking for updates

Customizing Pull

The Pull class takes updates from a foreign source and copies to itself. In this example, we'll customize the receive method to post updates to our API server;

const Pull = require('indexeddb/lib/pull')

class PullIntoAPI extends Pull {
  receive(updates) {
    if (!Array.isArray(updates)) updates = [updates] // We may get one update or an array of updates, depending on what we sync with

    updates.forEach(function (update) {
      if (update.action == "add" && == "articles") {
        myapi.put("/articles", options.doc, function (error) {})

Custom Synchronization

After we defined the custom Push & Pull functions, we are ready to hook them. Simply create an object of these two and pass it to the sync method of the database that you want to sync with. Check the example below;

const local = require('indexeddb')('local', {
  version: 1

  pull: new APIPush,
  push: new APIPull


See test folder.


I use prova for testing. After running the following commands, open up localhost:7559 see the results:

  • Simple create/update tests: node test/crud.js -b
  • Select queries: node test/select.js -b
  • Sync:
    • Start sample sync backend: node test/fixtures/sync-server.js
    • Run frontend tests: node test/custom-sync.js -b -y "/sync-api=http://localhost:3000"


Well-tested, low-level wrapper around the IndexedDB API. It can sync locally and remotely.



No packages published
You can’t perform that action at this time.