Expert — Getting Started
This manual assumes React, TypeScript, and React Router are everyday tools, that you have touched the Supabase or Stripe SDK at least once or twice, and that you have handed code to Claude Code or Codex at some point. Hearing the term FSD before is enough; the six-layer dependency direction, the API adapter, and the RLS policy seat are picked up in the next section, architecture.
What follows is not a command reference. It is the reasoning behind the shape. Walk through that once, and architecture, build-and-package, and distribution all read in context.
The problem in one line
Section titled “The problem in one line”Hand a SaaS to an AI and the first two or three prompts produce something reasonable. After that, the structure starts drifting. The service_role key leaks into the client bundle, the same route path string ends up scattered in five places, and an RLS policy hand-built in Supabase Studio disappears in the next environment. saas-base puts guardrails exactly where that happens.
Three guardrails
Section titled “Three guardrails”FSD’s six layers, plus eslint-plugin-boundaries and jsx-a11y
Section titled “FSD’s six layers, plus eslint-plugin-boundaries and jsx-a11y”Folder layout follows Feature-Sliced Design, and eslint-plugin-boundaries enforces import direction at build time. If the AI tries to cut across layers in arbitrary ways, the build refuses. jsx-a11y rides alongside on the same pass and catches accessibility violations. An <img> without alt or an <input> without a label is rejected right there.
A single seat for the API adapter
Section titled “A single seat for the API adapter”src/shared/api/server/ holds the adapter strategy. The default is Supabase Edge Functions (supabase.functions.invoke(...)). The options are Hono on Node or a Cloudflare adapter. Slices in features never know which adapter is in play; they call the same interface. Once the adapter decision is recorded in .claude/state/api-adapter.json, you can switch the backend runtime without touching the calling code.
A single seat for RLS policies
Section titled “A single seat for RLS policies”Every RLS policy lives in api/migrations/<timestamp>_<name>.sql. Policies are never built through Supabase Studio’s UI. Git does not track those, and they are where drift between environments leaks in. supabase db push ships the same SQL into whichever environment.
ADR habit
Section titled “ADR habit”Decisions that are expensive to undo go into docs/adr/, one per page. Why the routing mode landed on marketing-app, why the API adapter is pinned to edge-functions, why pricing plans split into monthly versus annual. Code records what was done; ADRs record why. The next session, or the next collaborator, picks up the intent without reverse-engineering it from the result.
The ADR template and when to write one sit in docs/adr/README.md.
Automation entry points point at the same place
Section titled “Automation entry points point at the same place”The Claude Code entry points are .claude/agents/ and .claude/skills/. The Codex entry point is the root AGENTS.md. Both routes read the same single file in the end.
AI_AUTOMATION.md. Domain rules, FSD slice mapping, SaaS forbidden patterns, the six-dimension review checklist, and the Phase 1 through 6 flow all live there. Two automation tools share one canonical document, so a decision settled in Claude Code carries through a Codex session as well.
What is missing right now
Section titled “What is missing right now”Parts of this base are not finished, and the manual does not hide it. The manual and landing site are public, but the template itself is on a commercial license model. The payment flow and buyer webhook are not wired yet. COMMERCIAL-LICENSE.md is in draft, lawyer review pending. Both have to land before actual sales.
There are gaps on the engineering side too. The src/ tree in saas-base is a placeholder skeleton until phase 5 (/5-customize-saas). Until you populate it with your own SaaS, the route tree, the domain entities, and the RLS policies are not real code. What this manual teaches is the procedure that fills that empty skeleton through the phase flow — it is not a reference implementation of saas-base itself.
What this manual does not cover
Section titled “What this manual does not cover”OS-specific setup, choosing a Node version manager, screenshots of the Supabase or Stripe signup screens, or a step-by-step walk for someone meeting a terminal for the first time — none of that lives here. For that, use the Beginner manual. Same base, different pace.
Architecture comes next. How the FSD six layers tie together by dependency direction, what route SSOT and the Supabase client SSOT look like in code, and how the three-step Stripe Checkout split runs, with two diagrams.