Project structure
A tour of every top-level directory in the ShipVeryFast boilerplate and where each feature actually lives, so you always know which file to open next.
Mental model
Routes and route handlers live in app/, reusable UI lives in components/, all non-UI logic (auth, Stripe, Supabase, security, AI) lives in libs/, and data shapes live in models/.
app/, the App Router
Everything in app/ is a route. Alongside the marketing pages and legal pages (app/page.tsx, app/privacy-policy/, app/tos/, app/blog/) you get the four product surfaces:
app/dashboard/, the authenticated user app, with its ownlayout.tsxand nested routes:analytics/,billing/,team/,customers/,api-keys/,notifications/,settings/andassistant/(the AI chat).app/admin/, the admin console:analytics/,pricing/,preferences/,deployment/andlaunch/(the launch checklist).app/settings/, account settings, includingsettings/appearance/for theming.app/login/andapp/signup/, the auth entry points.
Route handlers (server endpoints) live under app/api/ and are covered next.
app/api/, route handlers
Each folder under app/api/ exports a route.ts. These are the server endpoints the app and external services call:
| Route handler | Purpose |
|---|---|
app/api/auth/[...nextauth]/route.ts | NextAuth.js handler (sign-in, callbacks, session) |
app/api/checkout/session/route.ts | Creates a Stripe Checkout session |
app/api/webhooks/stripe/route.ts | Stripe webhook events (subscriptions, payments) |
app/api/webhooks/mailgun/route.ts | Mailgun delivery / event webhooks |
app/api/security/audit/route.ts | Security audit log access |
app/api/security/alerts/route.ts | Security alerts feed |
app/api/feature-flags/route.ts | Reads feature-flag state |
app/api/csrf-token/route.ts | Issues a CSRF token |
app/api/config/route.ts | Exposes safe runtime config to the client |
app/api/ai/chat/route.ts | Streaming AI chat (Zod + session + rate limited) |
components/, the UI library
Reusable React components, grouped by concern. The top-level barrel is components/index.ts.
components/ui/, the shadcn/ui primitives (button.tsx,card.tsx,input.tsx, …) plus sub-folders likeui/admin/,ui/analytics/,ui/form/andui/pricing/.components/dashboard/, the dashboard shell and widgets (DashboardSidebar.tsx,DashboardTopbar.tsx,StatCard.tsx,DataTable.tsx,CommandPalette.tsx,charts/).components/landing/, marketing sections (Hero.tsx,Features.tsx,Pricing.tsx,FAQ.tsx,Testimonials.tsx).components/auth/,AuthForm.tsxandAuthShell.tsx.components/admin/,AdminSidebar.tsx.components/theme/,theme-provider.tsx,theme-selector.tsx,theme-toggle.tsx.components/security/,AuditTrail.tsxand its barrel.components/providers/, context providers (FeatureFlagsProvider.tsx,AnalyticsProvider.tsx,QueryProvider.tsx,LazyLoadProvider.tsx).components/examples/, demo components such asAdvancedFormExample.tsxandFeatureFlagExample.tsx.
libs/, application logic
All non-component logic lives here. A few of the load-bearing modules:
| Module | Role |
|---|---|
libs/config.ts | Zod-validated environment schema (env) |
libs/supabase.ts | Supabase client + admin client |
libs/auth.ts | NextAuth.js configuration |
libs/stripe.ts · libs/pricingPlans.ts | Stripe SDK wiring and pricing definitions |
libs/rateLimiter.ts | API / auth / sensitive-op rate limiters |
libs/csrf.ts · libs/useCSRF.ts | CSRF token generation and validation |
libs/securityLogger.ts | Structured security-event logging |
libs/emailService.ts · libs/mailer.ts | Mailgun email sending and templates |
libs/ai/ | Provider-agnostic AI layer (Anthropic + OpenAI) |
libs/dashboard/ | Dashboard nav (nav.ts), store, chart theme, demo data |
libs/themes.ts | Theme tokens and scheme definitions |
libs/ai/ is itself a small package: index.ts (the getProvider / allProviders registry), plus anthropic.ts, openai.ts and types.ts.
models/, Zod schemas
Type-safe data shapes, each exporting a schema and an inferred type, re-exported from a central barrel at models/index.ts:
// models/index.ts
export { userSchema, type User } from './user';
export { subscriptionSchema, type Subscription } from './subscription';
export { paymentSchema, type Payment } from './payment';
export { blogPostSchema, type BlogPost } from './blogPost';So app/dashboard code can do import { userSchema, type User } from "@/models" and get both the runtime validator and the TypeScript type from one import.
middleware.ts & middleware/
middleware.ts at the repo root is the single Next.js middleware. It composes the cross-cutting protections by importing from libs/ and the middleware/ folder:
- Auth gating via
withAuthfromnext-auth/middleware. - Rate limiting via
apiRateLimiter,authRateLimiterandsensitiveOpRateLimiterfromlibs/rateLimiter. - CSRF checks via
validateCSRFFromRequestfromlibs/csrf. - Security monitoring via
securityMonitorfrommiddleware/securityMonitor(themiddleware/folder also holdsrateLimit.ts).
tests/, scripts/ & supabase/
tests/, split intounittargets (tests/components/,tests/libs/,tests/api/),tests/integration/andtests/e2e/(Playwright), with sharedhelpers/.scripts/, developer helpers, includingdevtool.js(run vianpm run devtool), aperformance/folder, andcapture-marketing-shots.mjs.supabase/migrations/, the SQL migrations; the schema starts atsupabase/migrations/0001_initial_schema.sql.
The @/* alias & barrels
tsconfig.json maps @/* to the project root ("@/*": ["./*"]), so every import is absolute from the repo root, no ../../../ chains. Combined with barrel files this keeps imports short:
// Flat import from the components barrel (components/index.ts)
import { Button, Card, ThemeProvider } from "@/components";
// Grouped helper objects also exist for theme, providers and security:
import { ThemeComponents, ProviderComponents, SecurityComponents } from "@/components";
const { ThemeProvider, ThemeToggle } = ThemeComponents;
// Libs and models resolve the same way:
import { env } from "@/libs/config";
import { getProvider, allProviders } from "@/libs/ai";
import { userSchema, type User } from "@/models";Next steps
- Config files reference, what every build & test config controls
- Tech stack, the dependency behind each directory
- Environment variables, what
libs/config.tsvalidates
