How flipthedream/agentkit works
1. What this repo is
- agentkit is a three-part fullstack framework for agentic workflows: a SvelteKit 5 frontend, a PocketBase-based backend extended in Go, and a NATS event bus.
- The architecture is intentionally “runtime-configurable” so the same frontend image can run in different deployments without rebuilding.
2. Top-level runtime shape
- The system runs as separate services:
- Frontend on :5173 in dev or :3000 in production
- Backend/PocketBase on :8090
- NATS on :4222 with WebSocket access on :9222
- A SQLite database lives inside PocketBase’s pb_data volume, so the backend is also the persistence boundary.
3. Backend subsystem
- The backend entrypoint is backend/cmd/server/main.go, which launches PocketBase in Go.
- backend/internal/pocketbase/ is the main extension layer: it bootstraps PocketBase, adds hooks, config endpoints, auth behavior, and any custom API behavior.
- PocketBase provides the core backend capabilities: auth, database access, file storage, and realtime API.
4. Backend-to-frontend contract
- The backend exposes /api/config, which is the key integration point for runtime configuration.
- That endpoint supplies browser-facing URLs such as:
- PUBLIC_POCKETBASE_URL
- PUBLIC_NATS_WS_URL
- It also exposes an internal SSR-facing URL:
- INTERNAL_POCKETBASE_URL
- This makes the backend the source of truth for deployment-specific connectivity.
5. Frontend subsystem
- The frontend is a SvelteKit 5 app using the modern runes-based model.
- frontend/src/routes/+layout.ts performs universal loading and fetches runtime config from the backend.
- frontend/src/lib/config.ts centralizes config resolution and provides build-time fallbacks if the backend is unavailable.
- frontend/src/lib/pocketbase.ts creates the PocketBase client, and frontend/src/lib/nats.svelte.ts handles browser NATS connectivity.
6. Browser vs SSR data flow
- The frontend uses a split model:
- SSR/server-side rendering talks to PocketBase through INTERNAL_POCKETBASE_URL over the Docker network.
- Browser-side code talks to the public PocketBase URL and to NATS over WebSocket.
- This avoids baking environment-specific hostnames into the frontend build artifact.
7. Messaging and realtime subsystem
- backend/internal/nats/client.go is the backend’s NATS client boundary.
- The repo’s NATS configuration lives in nats/nats-server.conf.
- The intended subject model is hierarchical, with patterns like:
- agentkit.>
- agentkit.heartbeat
- agentkit.events.*
- NATS is used for cross-service pub/sub and realtime event propagation, separate from PocketBase’s own API/realtime layer.
8. Deployment boundary
- The repo supports three operational modes:
- Development with hot reload (air for Go, Vite HMR for SvelteKit)
- Self-built production via multi-stage Docker images
- Deploy mode using prebuilt GitHub Container Registry images
- Compose files separate these concerns:
- docker-compose.yml
- docker-compose.prod.yml
- docker-compose.deploy.yml
9. Infrastructure and packaging
- Docker is the main orchestration boundary across all environments.
- Backend and frontend each have dev and prod Dockerfiles, indicating distinct runtime packaging strategies.
- The backend image is expected to run PocketBase in server mode on 0.0.0.0:8090; this is important because the healthcheck and deploy flow depend on that command shape.
10. CI/CD flow
- GitHub Actions (.github/workflows/build.yml) builds and validates the project.
- On main, it publishes latest and main images to GHCR; tagged releases publish semantic version tags.
- This means the deployment story is image-driven rather than source-driven.
11. Where extension points live
- Backend customization belongs in backend/internal/pocketbase/ for hooks, auth, API extensions, and OAuth wiring.
- Messaging conventions belong in backend/internal/nats/ and nats/nats-server.conf.
- UI additions belong under frontend/src/routes/, with SvelteKit file-based routing mapping directly to URL structure.
12. How to draw the architecture
- Draw the frontend as the browser-facing shell, with SSR and client-side paths.
- Draw the backend as PocketBase plus Go extensions, owning auth, config, persistence, and backend event integration.
- Draw NATS as a separate eventing layer, connected to the backend and directly reachable from the browser via WebSocket.
- Show SQLite/PocketBase storage as the backend’s internal persistence boundary, not a separate app database service.
Main entry points: routes SvelteKit app · pocketbase.go PocketBase ext · main.go Server entry · build.yml Build workflow
Components 18
Frontend
SvelteKit browser shell with SSR and client-side runtime config.
- SvelteKit app · Browser-facing UI shell and routing layer.
frontend/src/routes - Runtime config · Universal layout loading that fetches backend-supplied runtime settings.
frontend/src/routes/+layout.ts - Config resolver · Centralizes browser and SSR config resolution with fallbacks.
frontend/src/lib/config.ts - PocketBase client · Client-side PocketBase connectivity for the app.
frontend/src/lib/pocketbase.ts - NATS client · Browser WebSocket connection to NATS.
frontend/src/lib/nats.svelte.ts
Backend
PocketBase server extended in Go for config, auth, and APIs.
- Server entry · Launches PocketBase in server mode.
backend/cmd/server/main.go - PocketBase ext · Bootstraps PocketBase and wires custom behavior.
backend/internal/pocketbase/pocketbase.go - Config API · Exposes runtime deployment config to the frontend.
backend/internal/pocketbase/pocketbase.go - Hooks & auth · Custom auth, hooks, and API extensions around PocketBase.
backend/internal/pocketbase/pocketbase.go - NATS boundary · Backend-side NATS client and pub/sub integration.
backend/internal/nats/client.go - PocketBase core · Provides auth, database, file storage, and realtime API.
- SQLite storage · PocketBase data volume and embedded SQLite persistence boundary.
Messaging
NATS event bus and subject conventions.
- NATS server · Standalone NATS broker with websocket access.
nats/nats-server.conf - Subjects · Hierarchical subject space for app events and heartbeats.
nats/nats-server.conf
Infra
Docker, compose, and release packaging.
- Compose files · Development, production, and deploy service definitions.
docker-compose.yml - Backend images · Dev and production Dockerfiles for the Go/PocketBase service.
backend/Dockerfile - Frontend images · Dev and production Dockerfiles for the SvelteKit service.
frontend/Dockerfile
CI/CD
Build and publish workflow.
- Build workflow · Builds, validates, and publishes release images to GHCR.
.github/workflows/build.yml
Connections 21
- SvelteKit app → Runtime config: loads config · Route layout performs universal config loading.
- Runtime config → Config API: fetches runtime config · SSR and browser both rely on backend-supplied deployment URLs.
- Config resolver → Config API: resolves from · Uses backend config when available and falls back when needed.
- SvelteKit app → PocketBase client: uses · UI reads and writes PocketBase through the browser client.
- SvelteKit app → NATS client: connects to · Browser establishes WebSocket access to NATS.
- Runtime config → Config resolver: normalizes · Layout-level config is funneled through the shared resolver.
- Server entry → PocketBase ext: starts · Entrypoint launches the PocketBase extension layer.
- PocketBase ext → PocketBase core: extends · Custom backend behavior is mounted onto PocketBase.
- PocketBase ext → Config API: serves · Backend exposes runtime config for browser and SSR clients.
- PocketBase ext → Hooks & auth: contains · Hooks, auth, and API customizations live here.
- PocketBase ext → NATS boundary: publishes events · Backend integrates with the event bus boundary.
- NATS boundary → NATS server: connects to · Backend publishes and subscribes through NATS.
- NATS server → Subjects: routes by · Broker uses hierarchical subject patterns for messages.
- PocketBase core → SQLite storage: persists in · PocketBase owns the embedded SQLite persistence boundary.
- Server entry → Compose files: runs under · Service startup is orchestrated through compose.
- SvelteKit app → Compose files: runs under · Frontend service is defined by compose environments.
- Server entry → Backend images: packages as · Backend runtime is built from dedicated Dockerfiles.
- SvelteKit app → Frontend images: packages as · Frontend runtime is built from dedicated Dockerfiles.
- Build workflow → Backend images: builds · CI produces backend container images.
- Build workflow → Frontend images: builds · CI produces frontend container images.
- Build workflow → Compose files: validates deploys · Workflow supports image-driven release and deployment flows.