Skip to main content

Developer Guide

This is the guide for engineers building on, deploying, or contributing to CivicOS. If you're a citizen or an organization admin looking to use CivicOS, head to the User Guide instead.

Where to start

  • New to the codebase? Start with Architecture — the 10-minute mental model.
  • Setting up your machine? Follow Running locally.
  • Working in a specific service? See the Services section — one page per service, focused on responsibilities and package layout.
  • Deploying? See Deployment — pointer to the Render blueprint in docs/deploy.md.

What CivicOS is, technically

CivicOS is a microservice-oriented civic engagement platform built in Go on the backend and React + TypeScript on the frontend. Four Go services (identity, community, organization, api-gateway) sit behind Postgres 16 and Redis 7. Two React apps (citizen web, admin console) consume the gateway.

  • One binary per service. Single Docker image per service.
  • pnpm workspaces + Turborepo hold the frontend and shared TS packages.
  • Go modules per service — no shared Go module, on purpose.
  • Everything talks HTTP + JSON. NATS is provisioned for future event-driven work.

Design principles

  1. Dependency injection everywhereNewRepository(db)NewService(repo)NewHandler(svc) in main.go. No hidden globals.
  2. UUIDs, not sequential IDsuuid.New().String() at construction time.
  3. Validate at boundariesbinding:"required" on input structs.
  4. Error codes, not raw messages — every error returns {code, message} so the frontend can localize.
  5. Timestamps in UTC — localize only in the UI.
  6. Files under 300 lines — split at 500.
  7. Never serialize secretsjson:"-" on password hashes, reset tokens, refresh tokens.

Details: Contributing.