Documentation

Under the hood

How Sideporch is built: one program, one database, and what happens inside when someone sends a message.

Sideporch is one program written in Rust. It serves the web pages, keeps live connections to browsers, runs automations and background work, and keeps everything in one data directory. There is no database server, message broker, cache or separate frontend to run next to it.

flowchart LR
  subgraph People
    B[Browsers and phones]
  end
  subgraph Sideporch["sideporch (one process)"]
    H[HTTP server
pages and forms] W[Live connections
WebSocket hub] P[Message pipeline] A[Automation workers
one thread each] T[Background tasks
reminders, backups,
updates, cleanups] end subgraph Data["Data directory"] D[(sideporch.db
SQLite)] F[files/
by SHA-256] K[secret.key] end B -- HTTPS --> H B <-- WebSocket --> W H --> P P --> D P --> W P --> A A --> D T --> D H --> F A -. secrets .-> K P -- Web Push --> X[Push services] P -- signed requests --> O[Other Sideporch servers]
What runs where. Everything inside the box is one process.

The parts

  • Pages are made on the server. Every page is HTML rendered by maud, styled with utility classes compiled into one stylesheet when Sideporch is built. Pages work without JavaScript; one small script adds live updates, sending without reloading, the emoji picker and other comforts.
  • Live updates travel over one WebSocket per open tab. A message is rendered once and sent to the tabs that show its channel; the others only hear that the channel has something new.
  • One database: SQLite in write-ahead-log mode holds people, channels, messages, settings and the search index. File contents live next to it on disk.
  • Automations run Lua 5.4 in a sandbox, each on its own thread with its own database connection, so one slow script never holds up chat.
  • Background tasks deliver reminders and scheduled messages, write scheduled backups, check for updates, deliver to connected servers, clean up old data, and reset demo servers.

The program is built as a single static file for Linux (x86-64 and ARM), and for macOS; the container image contains nothing else.

Read on

The decisions behind all of this, with the alternatives considered, are recorded in the repository’s decisions/ directory.

  • How a message travelsWhat happens between pressing send and the message showing on everyone's screen.
  • Data and storageThe database, files on disk, search, upgrades between versions, and backups.
  • Automations insideHow automations run: a worker per script, a Lua sandbox, budgets, and how events reach them.
  • SecurityHow Sideporch signs people in, keeps sessions, limits abuse, stores secrets and checks updates.