Architecture
A modular, production-first baseline with clear boundaries and safe defaults.
The edd Starter template uses a structured, modular architecture. It moves away from generic, unorganized boilerplate folders and instead groups files by vertical product capabilities. This keeps features separated, prevents circular imports, and allows you to scale the codebase easily.
System Layers
The application is divided into three layers to keep technical infrastructure separate from business logic:
- App Shell & Routing: Handles top-level page routing, global layout shells, authentication route guards, and theme settings.
- Domain Modules (
src/modules/*): Decoupled folders representing specific business capabilities (e.g.modules/aifor assistant actions,modules/authfor credentials). Each module encapsulates its own views, server actions, config, and state schemas. - Shared Layer (
src/shared/*): Cross-cutting services and helpers that don't contain business logic, such as the database client, validation frameworks, Sentry configs, and generic UI components.
Routing & SSR
We use TanStack Start & TanStack Router for 100% type-safe, file-based routing. This includes server-side rendering (SSR), hydration management, and search parameter validation:
- Pathless Routing: Folders prefixed with an underscore (like
_landingor_docs) group pages sharing identical visual shells without changing the URL path. - Server Actions & Hydration: Data fetch operations are handled in route loaders, meaning page data is fetched on the server and hydrated on the client with full type safety.
Module Isolation Rules
To prevent the codebase from becoming difficult to maintain, modules must follow strict boundaries:
⚠️ Crucial Convention: Zero Cross-Module Imports
Files inside src/modules/ai/ must never import from src/modules/auth/. If two modules need to share a capability, that capability must be promoted to a shared module under src/modules/shared/ or moved into the src/shared/ layer.
Data Synchronization Flow
The application coordinates client-side state with server database models using a clear data flow:
- Route loaders fetch the initial data on the server during requests.
- React Hook Form handles user input validation using schemas defined with Zod.
- TanStack Query triggers mutations, validates data, updates cache layers, and manages optimistic UI states on the client.
Architectural Layer Map
The diagram below shows how requests flow through the application, moving from client views down to domain modules and shared utilities:
