SaaS Starter

AI-ready

How this boilerplate is optimized so an AI agent can write code that actually works.

Philosophy

LLMs don't read your mind — they read your code. An AI-friendly boilerplate minimizes ambiguity: exact types, repeated patterns, explicit ADRs.

Types as contract

@app/contracts exports Zod schemas and inferred types. An agent that reads the contract knows exactly which payload to send and what to expect back. No documentation to rot.

import { CreateUserInput } from '@app/contracts';
// The type is the doc.

Branded IDs

UserIdOrganizationIdstring. If an agent confuses one for another, the TS server catches it before the commit. Fewer subtle bugs.

Result instead of throws

LLMs propagate errors better when they are values. Result<T, E> maps naturally to JSON, to tests, to docs.

Versioned ADRs

docs/adr/ documents architectural decisions (why BetterAuth, why provider-agnostic billing). An agent reads the ADR before proposing a change that contradicts it.

Generators

bun run gen:domain <name> scaffolds a complete aggregate (entity, VOs, repo, use cases, controller, tests). The agent follows the existing pattern instead of inventing a new one.

MCP-friendly

Prisma schemas + OpenAPI generated at apps/server/openapi.json. Any agent with OpenAPI tools explores the API without guesswork.

Repeated patterns

Every aggregate has the same structure (domain/, application/, infrastructure/, interface/). An LLM learns the pattern in one bounded context and replicates it in the next without friction.

On this page