How SpipCP is built
The technology stack behind SpipCP — the frameworks, database, and tooling the panel, worker, and agent are built on, and the principles that shaped the choices.
This page is for the curious and the contributor: what SpipCP itself is made of. The stack is kept small and simple where it matters — one database, no extra services, typed end to end.
At a glance
| Layer | Technology |
|---|---|
| Web UI | React 19 + TanStack Start (full-stack React) + TanStack Router |
| Styling | Tailwind CSS v4 + Base UI, with a custom graphite/white design language |
| API | oRPC + Zod → typed RPC and an OpenAPI/REST surface from one definition |
| Auth | better-auth (password + TOTP, sessions, invites) |
| Database | PostgreSQL + Drizzle ORM — the single source of state |
| Jobs | pg-boss — a durable queue inside Postgres (no Redis, no broker) |
| Fleet agent | A small static Go binary on each node, over a secure WebSocket |
| Reverse proxy | Caddy (TLS termination, routing) |
| Packaging | Docker Compose · pnpm monorepo |
| Docs | This site — Fumadocs + TanStack Start |
The shape of it
Fleet agent (Go) ←WSS→ Worker (panel) ←Postgres→ Web (panel, React)The panel is one application with two faces: the React web UI and a background worker that runs the job queue and talks to the agents. The agent is a small Go binary installed on each node; it connects out over a WebSocket, so nodes need no inbound ports open. All durable state — jobs, fleet state, audit — lives in one PostgreSQL database.
Principles behind the choices
| Principle | What it means in practice |
|---|---|
| One stateful service | Postgres holds everything. The job queue is a table, so it survives restarts — no Redis, no broker to operate. |
| Typed end to end | One validated definition serves the web UI, the REST/OpenAPI surface, and the agent contract, so the pieces can't drift apart. |
| The panel decides, the agent acts | The panel never SSHes a node to run things; it computes desired state and the agent applies it. |
| API-first | Every capability is on the API before the UI — the web app is just one client of /api/v1. |
| Self-hosted, no lock-in | Open-source components, your infrastructure, direct connections between panel and fleet. |
The repository
SpipCP is a pnpm monorepo. If you want to build or contribute, Project layout maps every package and Development setup gets it running locally.
→ Security architecture: Security. · What you can install with it: What you can install.