Skip to content
This repository has been archived by the owner. It is now read-only.


Switch branches/tags

Latest commit


Git stats


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

SSB browser demo

Screenshot of ssb browser demo

A secure scuttlebutt client interface running 100% in the browser. Built using ssb-browser-core. This was originally made as a demo for my bornhack talk.

The client was made for two purposes: test ssb in a browser and for evaluating different partial replication strategies.

Feeds are stored in full for feeds you follow directly. For feeds followed by a feed you follow (hops 2), you only store a partial replica of their messages.

If you are a new user, the best way to get started is to get the id of a person already on the network, go to their profile page and start following that person. After this you will start seeing their messages and the messages of their extended graph. In order for them to see your messages, they will need to follow you back. You can get your id on the profile page.

As a way to let people explore the messages from users outside ones follow graph, the ssb-partial-replication plugin is used to get threads from the server.

The UI is written in vue.js and can display posts and self assigned profile about messages.

Things that work:

  • partial replication
  • direct connections to other peers using rooms
  • viewing posts and threads, including forks, backlinks and reactions
  • posting, adding reactions, replying to messages including posting blobs
  • automatic exif stripping (such as GPS coordinates) on images for better privacy
  • automatic image resizing of large images
  • viewing profiles and setting up your own profile
  • private messages including private blobs
  • offline support and PWA (mobile)
  • ooo messages for messages from people outside your current follow graph
  • deleting messages included a whole profile
  • blocking
  • channels
  • groups
  • forum like view
  • notifications
  • themes
  • translations
  • backup / restore feed using mnemonics
  • easily run alternative networks

Tested with Chrome and Firefox. Chrome is faster because it uses fs instead of indexeddb. Also tested on android using Chrome and iOS using safari.

An online version is available for testing here

Running locally

For testing this locally, one needs to run a local http server like npm i -g http-server.


I made a blog post on how to run a server pub to relay messages to other nodes through.


npm run build for developing and npm run release for a much smaller bundle. You can also run npm run inline to genereate a single monolithic index.html file with all resources included.

Enabling WebSockets in ssb-room

To run an ssb-room which this can connect to, you will need to enable WebSockets support. This requires three things:

  1. In ssb-room's config.js, add a line to connections to configure the WebSockets port (external, key, and cert need to be customized for your installation):
  connections: {
    incoming: {
      net: [{ port: 8888, host: "", scope: "public", transform: "shs" }],
      ws: [{ port: 9999, host: "::", scope: "public", transform: "shs", external: [""], http: true }],
      // Or, to use secure WebSockets:
      // ws: [{ port: 9999, host: "::", scope: "public", transform: "shs", external: [""], key: "/etc/letsencrypt/live/", cert: "/etc/letsencrypt/live/" }],
    outgoing: {
      net: [{transform: 'shs'}],
  1. Run either npm install -g ssb-ws to install the WebSockets connector globally, or cd into the ssb-room directory and npm install ssb-ws
  2. In index.js, add the following line to the SecretStack section just below ssb-logging:

After that, your ssb-room will be compatible with ssb-browser-demo.


How to help with translating

If you know a language other than English, we need your help! Take a look at our translation efforts here:

Issue #103

We currently have support for English (US), English (UK), English (Pirate), and mostly machine-translated Japanese. To add a translation, take a look at messages.json. You'll find sections in there for the different languages we support. Just take an existing language block (like "en") and copy it to a new block with the locale's name as the key, and start translating!

As a side note, we use vue-i18n for internationalization, which supports fallback locales. So, for example, if your locale is "en-US", then when it finds that we don't have a specific "en-US" translation, it falls back to the generic "en". The same would be true of "fr-CH" if we had an "fr" translation, for example. So if your translations are generic enough to be used by multiple local variants, please put them into a generic language block.

Force WASM locally (outside browser)

rm -rf node_modules/sodium-chloride/

check contents of db

var pull = require("pull-stream")

  pull.drain((msg) => {

List all files in browser

function listDir(fs, path)
  fs.root.getDirectory(path, {}, function(dirEntry){
    var dirReader = dirEntry.createReader();
    dirReader.readEntries(function(entries) {
    for(var i = 0; i < entries.length; i++) {
        var entry = entries[i];
        if (entry.isDirectory) {
            console.log('Directory: ' + entry.fullPath);
            listDir(fs, entry.fullPath)
        else if (entry.isFile)
            console.log('File: ' + entry.fullPath);

window.webkitRequestFileSystem(window.PERSISTENT, 0, function (fs) {
  listDir(fs, '/.ssb-lite/')