How we built OrbitDB Time Machine


OrbitDB Time Machine


OrbitDB is a decentralised database management system. OrbitDB, and decentralised platforms in general, offer a new way of developing inherently decentralised applications, such as a chat platform or real-time multi-user document editing software. In contrast to traditional, centralised applications, this avoids the cost of requiring a large central server, through which all traffic passes. With emerging technology such as blockchain, and issues such as net neutrality, decentralised network architectures are becoming increasingly important.

New software such as IPFS and OrbitDB are steps to provide a developer ecosystem for decentralised applications as rich as the one around traditional, centralised applications. Unfortunately, it is harder to ensure functional correctness for such software, as the state of different nodes is not kept track of by a single central source of truth. This is harder for the developer to reason about, and may introduce bugs. Our project aims to solve this problem by developing a “logical time machine” debugger for OrbitDB. If we hope for widespread adoption of decentralised technology, a software ecosystem will be critical to lower the barrier of entry and the cost of learning a new way of thinking, and our project should be a contribution to this ecosystem.

So what is the OrbitDB Time Machine?

The OrbitDB Time Machine consists of two parts:

  1. The web UI - no longer maintained due to frequent breaking changes in IPFS

  2. The logger NPM package

The web UI displays the underlying OpLog of the database you opened. If you want to learn more about the inner workings of OrbitDB, including how the OpLog CRDT works, the official OrbitDB field manual is a great place to start!.

The web UI also displays any join events that it observed. Selecting these join events will rever the state of the oplog to display all of the oplog’s heads that were present at that join event. However, only join events from the perspective of the peer that is running the web UI will be shown.

If you want to see join events from other perspectives, we have the solution for you: The second part of the Time Machine, the logger package. Simply install the logger on any client’s code from whose perspective you wish to view the join events. Cool fact: The logger package actually also uses an OrbitDB database to store the information that it collected.

Who is it for?

The OrbitDB time machine is great for anyone! That’s right: You’ve never heard of OrbitDB? Just hop into our web UI and explore OrbitDB for yourself, without writing a single line of code. Or you’re alredy a seasoned OrbitDB dev? Our tool makes it easy for you to add visual logging functionality to your applications!

Try it yourself!

Make sure that you have an OrbitDB database running on version 0.22.0. Then simply enter the database address in the web UI. It doesn’t matter which type of store you are using - we support all five default stores available. Or, if you’re a newcomer to OrbitDB and just want to try OrbitDB out, you can easily also create a database from within our app!

If you want to add the logger package to an existing application, that’s easy too! Just follow these steps:

Install the logger package:

npm i --save orbit-db-time-machine-logger

In you application:

import Logger from 'orbit-db-time-machine-logger'

// ... Code to set up your OrbitDB instance ...
// This code will create an OrbitDB store

var logger = new Logger(store)


1. Action Bar

These are the available modifying operations on the particular database type. In this case, we are looking at a KeyValue database type, which supports the following operations:

  • put: Adds a key-value pair into the database

  • set: Modifies a key-value pair if it exists

  • del: Deletes a key-value pair if it exists

As such, the available operations will be different depending on the database type.

2. Perspective Selector

The perspective selector allows you to select from wich node’s perspective you are viewing the oplog. Either click in the box and select a user identitiy, or type the user identitiy directly.

Changing the perspective changes the logging data used to the data collected from the selected node.

3. Join Events

This bar encapsulates the time-travelling functionality of this application.

This application will keep a record of every time a JOIN-conflict has been resolved (straightforward joins are ignored). A JOIN-conflict typically refers to case where the Operations Log DAG has a branch after two versions have been JOIN-ed.

Clicking on any of the JOIN events within this bar will change the Operations Log View to the point of occurrence of the selected JOIN event.

4. Display Limit

Allows users to change the maximum amount of nodes to display. Increasing this value may lead to bad performance.

5. Operations Log View

The entries for the underlying Operations Log will be displayed here. You can see the manner in which the entries are ordered, especially after join events have been resolved through the CRDTs.

There are available interactions with each entries in this view.

  • Hovering

You can hover over the entry node, which will display a summary of the entry’s information.

  • Clicking

Clicking on an entry will render the Database Display. This will display the state of the database at that particular entry. The state is obtained by replaying the events from the beginning of time, up till the selected entry.

Depending on the database type, you may encounter different display formats. For instance, the Counter database type will simply display a numeric counter.

Who are we?

We are a team of five students from Imperial College London. This project was undertaken as part of the third year group project module, in collaboration with Haja networks.

Want to contribute?

That’s awesome! Contributions to our project would be most welcome. You can find our Git repository on We welcome any pull requests! We have also used JsDoc to document our code, so getting started should be a breeze!

By Hannes Hertach