Architecture overview
Alcoves is two deployable units that meet at a reverse proxy: a Nuxt 4 frontend on its own Nitro server, and a Go API backend. The Go binary is a pure API — it does not embed or serve the frontend.
This page is the map; the rest of the section drills into each subsystem — backend, frontend, database & migrations, media processing, storage backends, and ML models & runtime.
Topology
Section titled “Topology” ┌─────────────────────┐ browser ───► │ Reverse proxy │ └─────────┬───────────┘ │ /api/**, /s/** ┌─────────────────┴────────────────┐ ▼ ▼┌───────────────┐ ┌──────────────────┐│ Nuxt (Nitro) │ │ Go API (Echo) ││ :3000 │ │ :3001 │└───────────────┘ └────────┬─────────┘ │ ┌──────────────────┼───────────────────┐ ▼ ▼ ▼ ┌────────────┐ ┌──────────────┐ ┌────────────────┐ │ PostgreSQL │ │ Dragonfly │ │ Local / S3 │ │ (GORM) │ │ (Asynq queue)│ │ blob storage │ └────────────┘ └──────────────┘ └────────────────┘In production both servers sit behind one reverse proxy; the proxy routes
/api/** and /s/** (public share pages) to Go and everything else to Nuxt.
Backend (Go)
Section titled “Backend (Go)”- Echo HTTP framework, GORM over PostgreSQL, Asynq for async jobs backed by Dragonfly/Redis.
- Modes (
ALCOVES_MODE):all,api, orworker— the same binary runs the request path, the workers, or both. - Session auth via an AES-GCM encrypted cookie; library access is enforced by middleware before any handler runs.
- Heavy work — transcoding, hashing, and all ML inference — is pushed onto the queue with status / progress / version columns so it never blocks a request and can be safely re-triggered.
Frontend (Nuxt 4)
Section titled “Frontend (Nuxt 4)”- Nuxt 4 (Vue 3) with the Nuxt UI v4 module, on its own Nitro server.
- SSR is scoped to
/s/**(public moment share pages); all other routes are client-rendered to avoid SSR-time backend coupling. - An isomorphic fetch wrapper forwards the session cookie on SSR and uses a Nitro proxy on the client.
The async pipeline
Section titled “The async pipeline”When a file lands, the API enqueues work rather than doing it inline:
- Ingest — SHA-256 hash and dedup (derived/trashed files ignored).
- Media — thumbnails, video proxy transcodes, audio waveforms.
- ML — CPU-only ONNX models for faces, objects, audio events, plus whisper.cpp transcription.
- Index — results become searchable and drive the activity feed.
This async-by-default design is what keeps the request path fast and the system degradable: if an optional dependency is missing, Alcoves falls back instead of failing.