Architecture overview

The FSH stack is a codegen pipeline. Declarative Jsonnet configs (Pydantic-validated) compile through a target-agnostic engine into a FastAPI backend, a typed React frontend, an OPA/Rego policy service, and a render sidecar. Generated apps pull shared logic from runtime libraries at load time; infra provisions the AWS/GitHub substrate.

See getting started to stand a project up.

How it fits together

The codegen engine holds no framework knowledge: it discovers scopes, orders operations, walks the config tree, and renders Jinja templates, then hands off to target plugins (in codegen-targets) that emit the be/fe/opa/render source. Generated code never re-templates shared logic — the backend calls into fsh-lib, the frontend consumes @fsh/components-library, the render sidecar consumes @fsh/codegen-render. infra deploys the result.

jsonnet config
  │  codegen (engine) + codegen-targets (be/fe/opa/render plugins)
  ▼
generated app: be/  fe/  opa/  render/
  │  at runtime: fsh-lib (BE) · @fsh/components-library (FE) · @fsh/codegen-render (render)
  ▼
deployed by infra (OpenTofu + Terragrunt) → AWS ECS/Aurora/ALB + static FE

Who owns what

The same split holds for every feature; each guide’s How it works only notes its feature-specific exceptions.

You write:

  • SQLAlchemy models (and their migrations).

  • The jsonnet config (be/config/*.jsonnet, fe/config/fe.jsonnet) — the declarative source of truth.

  • Python glue the config references by dotted path: pre/post hooks, can guards, action handlers, serializers, comms transports/renderers/resolvers, OPA loaders, auth domain types.

  • The Rego rules, and the safe-to-edit FE scaffolds — field catalogs, enum displays, action modules, pages.

Codegen generates — never edit:

  • The BE routes/handlers, pydantic request/response schemas, serializers, and the OpenAPI spec.

  • The OPA baseline (RBAC + schemas) and each resource’s _generated/{module}/….

  • The whole TypeScript client — types, sdk, queries, tables, action catalogs, the auth bridge — under fe/src/_generated/.

Two write modes: everything under _generated/ is overwritten every run; scaffolds (if_exists=skip) are written once, then yours. Each guide’s code labels — Generated (do not edit), Scaffolded, safe to edit, You write — mark which is which.

The repositories

Repo

Kind

Deployed by infra?

What it does

codegen

tool

no (published lib/CLI)

Target-agnostic generation engine (pkg codegen, fka foundry): config → templates → BuildStore → target assembler.

codegen-targets

tool

no (published libs)

uv workspace of target plugins under packages/: codegen-be(-root), codegen-fe(-root), codegen-opa, codegen-render-root.

codegen-database

tool

no (published lib/CLI)

Dimension configs → SQLAlchemy models + Alembic migrations (pkg codegen_database, fka pgcraft).

python-lib

runtime lib

no (published to CodeArtifact)

Publishes fsh-lib (fka ingot): spec-invariant BE runtime (auth, db, queue, comms, telemetry, reports, opa, RBAC) the be templates emit into.

components-library

design system

no (published to CodeArtifact)

@fsh/components-library React design system + @fsh/codegen-render render library/Hono runtime.

codegen-example-app

generated app

yeslive/internal/example

Kitchen-sink reference app (be/opa/render ECS + static FE); round-trip validation harness.

sales-pipeline

generated app

yeslive/internal/sales-pipeline

Deployed sales-domain app: FastAPI + pgqueuer worker (app.queue.main:main), all four sides.

codegen-template-app

generated app

no (source/CI only)

Clone-and-fork starting point; just bootstrap scaffolds all four sides.

cli

tool

no (published fsh-cli)

fsh dev/ops surface: SSO login, ecs/secrets/db psql, CodeArtifact auth bootstrap.

just-package-manager

tool

no (published just-pm)

Package manager for just: vendors shared modules, pins just.lock.

just-packages

tool

no (source/CI only)

Shared just recipe modules (check/gen/dev/build/db/queue/deps) vendored via just-pm.

guides

tool (docs)

yes — live/docs (pages-guides)

This Sphinx/MyST docs hub; cross-cutting stack concepts.

renovate

infra service

yes — scheduled runner

Self-hosted Renovate config + cron; opens dependency-bump PRs org-wide.

infra

infra

self

OpenTofu + Terragrunt IaC; the control plane for everything below.

  • codegen — the engine; depends only on generic tooling (typer, pydantic, jsonnet, jinja2). Every target repo depends on it via the codegen.targets entry-point group.

  • codegen-targets — the six plugins holding all framework knowledge (FastAPI/SQLAlchemy, openapi-ts + react-query, Rego RBAC, render service, *-root bootstraps).

  • python-lib / fsh-lib — the BE “libc”: byte-identical across generated apps; its public signatures are an ABI version-coupled to the be templates.

  • components-library — the FE analog: design system plus the render library whose openapi-ts plugin turns the BE render-contract.openapi.json into per-template types.

  • infra — Terragrunt + OpenTofu; deploy target and control plane for all siblings (it even declares the GitHub repos themselves).

What infra tracks

infra is a Terragrunt + OpenTofu (Terragrunt Stacks) monorepo. Each environment is its own vended AWS account under a management account that owns the AWS Org. It enumerates every org repo in live/source-code (teams, branch protection, CI deploy keys), wires per-repo CodeArtifact publish/read roles in live/package-registry, deploys codegen-example-app and sales-pipeline as full per-tier stacks (VPC/Aurora/ECS/ALB/ECR/S3) under live/internal, and publishes Cloudflare Pages docs sites via live/docs. See infrastructure for detail.