Homepage Posts Contact

How to make a decentralized like button

On by Lorenzo Setale

All static websites meet a hard limit when a comment form, “like” buttons or any interactive content is required. These extra component are forcing people to build an API, host a server, a database or pay for any SaaS product that does that… we could write a blog post about that, but it would be too easy! Instead in this article I wanted to challenge myself a little more and explore how to make a decentralized like button: We will try how it is to not be hosting any server or database, and instead use a p2p networks and a decentralized database to count the likes

Decentralized vs Centralized

To achieve that I have been considering just one decentralized technology that I am very familiar with: the Interplanetary File System. This will allow us to make a simple HTML widget that works on any modern browser and gets data to show from a big and established p2p network.

As always, you can access the source code on GitLab. There is a website to see the results here: https://dlike.qm64.tech/ and set up

A little bit about IPFS and OrbitDB

The Interplanetary File System (AKA, IPFS) is a peer-to-peer hypermedia protocol. IPFS allows us to send and receive data using some concepts that are similar to BitTorrent. This video from 2018 explains in short what IPFS is.

OrbitDB is one of few databases that uses IPFS API to replicate and distribute content across the peers. It supports JavaScript, it runs in any modern Browser and it looks [documented enough].

OrbitDB / IPFS logo

This means that the data generated by the widget (the clicks) will not be stored in a central SQL/NoSQL database, but it will be spread across all the page viewers. Using OrbitDB and IPFS allows us to build a like button that doesn’t require a Blockchain nor a central server.

This page is all briefly about how to use IPFS and OrbitDB to create a decentralized application (dApp) as an HTML widget for our websites, to record likes/votes from users.

The Goals

I will consider Qm64 as our use case for this widget: this blog is generated with Hugo and adding a Like button would require to use an external service (ex: Facebook or Disqus) or to set up my own centralized server. Instead it needs a HTML widget that can be copy pasted and customized a little, similarly to Disqus or Facebook or other social buttons.

In short the goals of this project are:

  • Make a decentralised HTML widget (dApp? dComponent?)
  • It should be a like button
  • It should store data on IPFS/OrbitDB
  • This widget should be able to show changes in real time
  • It should automagically connect to the network
  • The user/website owner should not care about too much tech details

The process

The first step is to set up a HTML widget in Preact using Webpack, that is the core part of the UI, but it is not the most interesting one! We will not cover this part.

In order to show something to the UI, we need to connect to the network: load IPFS and OrbitDB instances to listen to events. To do so we are using something similar to the following lines:

const IPFS = require('ipfs')
const OrbitDB = require('orbit-db')

 .then((orbit) => { 
   // some magic here

OrbitDB supports different type of databases. We are developing a simple like button therefore a Counter database will work just fine. 😛 On top of that, as the users are going to click it without any authentication, we need to allow anybody to make changes. Last thing required is to find a name for the database. This is done with the following lines:

  // Give write access to everyone
  accessController: {
    write: ['*']

// Creating the database as counter with the custom options
const db = orbit.counter("qm64-tech", DATABASE_OPTIONS)

This will create a new database that will be identified with an unique ID. It is important that we note this ID: We need to use it to allow browsers/peers to find each other and fetch the data! 📡📡📡 For convenience I refer to this ID as the dbkey:

const dbkey = db.address.toString()
// it will log something like `/orbitdb/Qmd8....Q3EVSU/qm64-tech`

Last thing we need to know is to try and learn how to increase the counter and check the latest value:

// Get latest value
console.log(db.value) // will log 0

// Increase the counter

console.log(db.value) // will log 1

That seems simple right? YES! Too simple! 😅 But that is the beauty of it: the database synchronization between peers is done in the background using IPFS and OrbitDB instances. 🚀 We can listen to specific events to know when the data is replicated too and that is useful to build react components and update the state.

What is left is to glue all this together in a React Component, then use it in a HTML widget that can be included everywhere. Since this page is about OrbitDB I created a page that generates a HTML code that can be copy pasted and added into the pages. The page shows also the button and allows you to insert an existing dbkey, so that you can test the widget from other devices too.

Try it out! Open on your browser dlike.qm64.tech, create a new widget and keep the page open. Then take another device (your phone or iPad for example) and go to the same page but under Existing Widget insert the dbkey shown on the other browser! It might take few seconds or tries but it should work! 😎

dlike setup example

In this gif you can see me setting it up. Then I am copy-pasting the same value on my iPhone and pressing the like button there while keeping the original page open. 🎉🎉 It works 🎉🎉


This project is quiet interesting. I was expecting it to be way more difficult but technically speaking a lot of problems have been solved already by different libraries and tools developed as part of IPFS and OrbitDB.

Sadly the final minimized build of the whole javascript widget is big! (1.83 MB) A lot of these implementations are required in order to have a fully decentralised and peer-to-peer network, some of them are related to cryptography some others are just mechanism to make it work. This would be solved if browsers would implement an IPFS node within their binaries, but only few are doing so… and not the popular ones!

Even if all went good on the first setup, the project is still young and lacking some features. One of these is the lack of a daemon to replicate data. This is important because of content distribution in the network: If nobody currently online has a copy of the database nobody will be able to see the button! I have been considering rewriting it using Textile‘s ThreadsDB as it has an implementation in Go and a hub to replicate content.

This means that we don’t need a central database or an API, but we still need a solution to replicate the content in the network to ensure that it is alive.

Are we ready yet for dApps?

There are a lot of thing sto consider. The like button is just an example and this conclusion might is based on a side-project that lasted merely 3 months.

So far what we conclude is that implementing a decentralized app (dApps) just with IPFS and OrbitDB but without using a blockchain is not enough! Why? In the current setup anybody could can create a simple script to sends likes on pages. Using Ethereum would force users to pay a small fee but will reduce the cost of such kind of attack on the website!

On top of that, as said before: it is required some sort of persistency to respect an SLA. Websites with huge amount of users could afford to have dApps (or components) but to have replicas is required also on Web 2.0 services to ensure an SLA.

Was this a success?


Concluding, the libraries and development tools are already available. We should all start developing more using these tech as it might be really the future! I believe that this experiment is a partial success. Even if we reached our goals, the infrastructure required needs some tweaking: the dev tools and libs are available, but we need major browsers to implement changes for major dapps to work without a lot of workaround. I would say that this like button works, but it is limited by the current state of development.

If you want to explore more you can read the following articles: