Frontend

This document describes the current frontend in this repository, which ships in two skins: Decent and ssbski.

What Decent and ssbski are

Decent is the browser UI for this repo’s local SSB node. It is served by plugins/decent-ui.js and, by default, is available at:

ssbski is a second skin of the same UI — a Bluesky-style layout with Discover/Following feed tabs, a trending sidebar, and a sticky centre-column header. It is served by plugins/ssbski-ui.js (both plugins delegate to lib/ui-server.js) and, by default, is available at:

The two are the same JavaScript bundle talking to the same local SSB node — only the stylesheet differs (style.css for Decent, ssbski-style.css for ssbski). UI modules that need to vary behavior between skins detect ssbski by checking for the ssbski-style.css stylesheet link (see decent/src/modules/core/app.js). The two public instances on the network are decent.evbogue.com and ssbski.evbogue.com.

Neither is a separate web app backed by a generic REST API. Both are browser clients built specifically around the local SSB server behavior exposed by this repo.

Build pipeline

The frontend source lives in:

The main build command is:

npm run build:web

That produces the built frontend under:

This directory is generated and is not committed to the repository (it is listed in decent/.gitignore), so a fresh clone must run npm run build:web once before the web UI will serve.

The current build flow browserifies the frontend entrypoint and generates the served index.html and stylesheet assets. Because Decent and ssbski share one JS bundle and differ only in CSS, this single command builds both skins — it emits style.css for Decent and ssbski-style.css for ssbski. Always rebuild both after any frontend or stylesheet change; never leave one skin stale.

Runtime model

At runtime:

  1. the HTTP server serves the Decent bundle
  2. the page is loaded in the browser
  3. the server injects websocket remote information into the HTML when needed
  4. the frontend connects back to the local sbot-compatible surface
  5. frontend modules render feed, profile, thread, git, and other UI behavior

Source layout

The important frontend areas are:

Plugin/module architecture

Decent uses a small plugin-style architecture.

Modules declare:

These are wired together at startup.

This pattern is important to the frontend architecture and should be preserved in explanations of how Decent works.

HTTP integration

The frontend is tightly integrated with the HTTP server in plugins/decent-ui.js (and, for the ssbski skin, plugins/ssbski-ui.js; both share lib/ui-server.js).

That plugin serves:

Installability and desktop notifications

Both skins are installable Progressive Web Apps. lib/ui-server.js injects the per-skin manifest link and service-worker registration, and serves distinct names, theme colors, and icons for Decent and ssbski.

The service worker does not cache the app shell. It exists to support installation and notification-click routing without risking a stale frontend against the live websocket connection.

Desktop notifications are explicitly enabled by the user from the Notifications screen. While the app is open, including when backgrounded or minimized, the frontend uses the same notification classifier as the in-app tab for mentions, private messages, replies, votes, follows, and relevant git activity. Closed-app background push is not implemented; that would require a separate Web Push server and subscription model. The Notifications screen displays the current browser permission state and provides a test-popup button after permission is granted. The browser can accept a notification even when the operating system suppresses it, so Chrome must also be allowed under macOS System Settings > Notifications.

Websocket integration

The server injects a window.PATCHBAY_REMOTE value into the served HTML when appropriate.

This gives the frontend the remote connection information it needs for websocket-based access back to the local node.

That means frontend behavior is partly determined at serve time by the runtime environment and current request.

Blob handling

The frontend relies on HTTP blob routes exposed by the same server:

This is part of how images and other blob-backed content flow through the UI.

Git integration

The same HTTP server also supports git routes.

This matters because Decent is not only a social/feed UI. In this repo, it also participates in a broader local experience that includes git-over-SSB behavior.

Practical development loop

Typical frontend work looks like:

npm install
npm run build:web
npm start

Then open the UI in the browser and verify behavior there.

Documentation rule for the frontend

Frontend docs should describe:

They should not require the reader to infer all of this from older Patchbay or historical scuttlebot assumptions.