Architecture

This document describes how the current ssbc repository is structured and how its major pieces interact.

High-level structure

The system has five main layers:

  1. Server bootstrap and command entrypoints
  2. Core database and RPC surface
  3. Plugins for social, invites, blobs, ws, and git behavior
  4. HTTP serving layer for Decent and related routes
  5. Frontend code in Decent

1. Server bootstrap

index.js

index.js creates the SSB server with secret-stack.

It establishes:

bin.js

bin.js is the CLI entrypoint.

It is responsible for:

This is the main path for running the node locally.

2. Core database layer

lib/db.js

lib/db.js is the current core storage implementation.

It provides the main local server methods, including:

This file is one of the most important pieces of the repository.

Why it matters

Historically, SSB stacks often depended on older indexing layers and plugin-specific query machinery. In this repository, the current implementation is centered on the database behavior exposed here.

That means architectural explanations should start from lib/db.js and current behavior, not from historical indexing assumptions.

3. Plugins

The repo uses plugins to extend the server with distinct features.

Key plugin categories

UI and HTTP

These handle:

Social and replication behavior

These handle:

Other SSB surfaces

Additional behavior is provided through loaded modules such as blobs, gossip, ws, private messaging, and replication-related packages.

4. HTTP serving layer

plugins/decent-ui.js

This plugin is the HTTP entrypoint for the user-facing web experience.

It serves:

It also attaches websocket handling to the HTTP server so the frontend can connect through the same general web surface.

plugins/ssbski-ui.js

ssbski is a second skin of the same frontend, served on its own port (default 8990). It reuses the same JavaScript bundle and the same serving logic — both decent-ui and ssbski-ui delegate to lib/ui-server.js — and differs only in the stylesheet it serves (ssbski-style.css instead of style.css). The two public instances are decent.evbogue.com and ssbski.evbogue.com.

Routing summary

Important routes include:

Write policy

The HTTP endpoints that mutate the node — POST /blobs/add and git git-receive-pack (push, plus its info/refs capability advertisement) — are governed by the top-level config key writes:

When a write is refused the server responds 403; for git push the refusal fires at the info/refs handshake so git push fails immediately with a clean message rather than partway through the pack. The policy is evaluated in lib/ui-server.js (writesAllowed) and enforced there for /blobs/add and in plugins/git-server.js for the git routes. Set it in ~/.ssb/config:

{ "writes": "local" }

5. Frontend

decent/

The frontend is a browser-based SSB client. It is served in two skins — Decent and ssbski — from a single shared JavaScript bundle (see the HTTP serving layer above).

It is organized as a plugin-style frontend with modules declaring needs and gives, wired together at startup.

Important frontend characteristics:

6. Git integration

plugins/git-server.js

This plugin exposes repositories over git smart HTTP while using SSB storage underneath.

Conceptually, it bridges:

This means the same local server can act as:

7. Docs architecture

There are now two documentation layers in the repo:

Current docs

These should describe how the repository works now.

Historical archive

These are historical/reference material, served behind a labelled archive banner. They describe the original Secure Scuttlebutt project and should not be treated as the architectural spec for this repo.

Practical mental model

If you are trying to understand the repo, the best order is:

  1. bin.js to see how the server starts
  2. index.js to see the server root and permissions
  3. lib/db.js to understand current core data behavior
  4. plugins/decent-ui.js to understand HTTP/web serving
  5. plugins/git-server.js for git behavior
  6. decent/ for frontend behavior

Design principle

The current architecture should be explained in terms of what the system does now:

That is more important than preserving explanations of legacy internals that are no longer the main implementation path.