Toast
Contributor

Getting Started

Everything you need to understand and contribute to the Toast codebase.

Toast is a TypeScript monorepo. The API server is Hono with Drizzle ORM and Better Auth. The admin panel is React 19 with TanStack Router and Zustand. Everything is wired together with factory functions and a composition root — no magic containers, no decorators, no global singletons.

Quick start

git clone https://github.com/TryGhost/Toast.git
cd Toast
pnpm install
pnpm dx

pnpm dx handles everything: starts Docker containers (PostgreSQL + MinIO), runs migrations, seeds a default site and admin user, and launches all dev servers. The API runs at http://localhost:3000 and the admin panel at http://localhost:5173 (login with admin@ghost.org / admin). See Local Dev Setup for the full walkthrough, TipTap token setup, and troubleshooting.

The td CLI

td is Toast's developer CLI — the equivalent of Laravel's Artisan. The most important command is td generate feature, which scaffolds most of an API feature with the multi-tenancy requirement baked in:

td generate feature newsletters

This creates a contract stub plus repository, service, controller, routes, schemas, and test stubs. You still add any table changes in shared/db/src/schema.ts and wire the new stack through the app entrypoints, but the repetitive API boilerplate is handled. See Your First Feature for a guided walkthrough of building on top of a generated feature.

The mental model

Every API feature is four layers: schema → repository → service → routes (see Request Lifecycle). Each layer is a factory function that receives its dependencies as parameters. Infrastructure and feature stacks are built at startup and then mounted through the API entrypoints. To understand an existing feature, follow the chain from the route back through the service to the repository.

Agentic-first development

Toast is built for a world where agents write most of the code. The philosophy: every rule is enforced by a tool, with the fastest possible feedback loop. If a human or agent has to remember a convention, it will eventually be forgotten. If a tool catches it in seconds, it never ships.

The enforcement stack runs in layers — each one catches problems earlier than the next:

LayerWhenWhat it catches
td generateBefore you write codeMissing siteId, wrong file structure, missing API boilerplate
lint-stagedOn commitFormatting, lint errors, import style (Oxlint + Oxfmt)
pnpm check:strictOn pushDependency boundaries (depcruise), dead exports (knip), structural anti-patterns (ast-grep), type errors, 100% test coverage, build failures
CIOn PRSame as push + commit message format + integration tests

No rule relies on code review alone. --no-verify is forbidden — if a hook fails, fix the issue.


On this page