Project structure
Everything in NextForge has a specific place. Here's the full file tree with each directory and file explained.
Full file tree
├── _variants/ # Database variant files (deleted after setup)
│ ├── mongodb/ # Mongoose-based auth + OTP logic
│ ├── supabase/ # Supabase-based auth + OTP logic + SQL schema
│ └── firebase/ # Firebase-based auth + OTP logic
│
├── actions/
│ ├── auth.ts # loginAction, registerAction, verifyEmailAction, logoutAction
│ └── email.ts # sendPasswordResetOTPAction, resetPasswordAction, resendVerificationOTPAction
│
├── app/
│ ├── (auth)/
│ │ ├── login/ # /login
│ │ ├── register/ # /register
│ │ ├── verify-email/ # /verify-email
│ │ ├── forgot-password/ # /forgot-password
│ │ └── reset-password/ # /reset-password
│ ├── dashboard/ # /dashboard (protected route)
│ ├── api/auth/[...nextauth]/ # NextAuth handler
│ ├── error.tsx # Global error boundary
│ ├── not-found.tsx # 404 page
│ ├── layout.tsx # Root layout
│ └── globals.css # Tailwind + CSS variable design tokens
│
├── components/
│ ├── auth/ # Form components for each auth page
│ ├── nav/ # Navbar, MobileMenu, NavLinks, ThemeToggle
│ ├── footer/ # Footer
│ └── ui/ # Button, Input, Modal, Loader, Toast
│
├── hooks/
│ └── useToast.tsx # Toast state + provider
│
├── lib/
│ ├── auth.ts # NextAuth configuration
│ ├── db/
│ │ ├── mongo.ts # Mongoose connection (MongoDB variant)
│ │ ├── models/ # User + OTP Mongoose models
│ │ └── supabase.ts # Supabase client — publishable + secret key helpers (Supabase variant)
│ ├── email.ts # Resend email templates + sender
│ ├── ratelimit.ts # Upstash Redis rate limiters
│ ├── sanitize.ts # XSS escaping + (MongoDB) NoSQL injection stripping
│ ├── tokens.ts # OTP generation, hashing, verification
│ └── validate.ts # Zod schemas for all forms
│
├── proxy.ts # Next.js 16 middleware (route protection + security headers)
├── setup.mjs # Interactive database setup script
└── types/
├── index.ts # ActionState, shared types
└── next-auth.d.ts # NextAuth session type extensions_variants/
Contains the three database backend implementations — MongoDB, Supabase, and Firebase. Each variant is a self-contained set of files: DB client, user model/schema, OTP model/schema, and auth action implementations.
setup.mjsreads this directory, copies the chosen variant's files into the correct locations, removes the unused deps from package.json, and then deletes _variants/ entirely. After setup, this directory does not exist.
_variants/ directly. It exists solely for setup.mjs to consume.actions/
Server actions — functions decorated with 'use server' that handle all form mutations. Two files:
auth.ts— loginAction, registerAction, verifyEmailAction, logoutActionemail.ts— sendPasswordResetOTPAction, resetPasswordAction, resendVerificationOTPAction
Every action follows the same pipeline: sanitize input → validate with Zod → check rate limit → execute DB operation → return ActionState.
app/
Standard Next.js 16 App Router structure.
(auth)/— route group for all auth pages. The route group wrapper means these pages share no special layout beyond root layout.dashboard/— the first protected route. Use this as your starting point for authenticated content.api/auth/[...nextauth]/— NextAuth v5 catch-all route handler.error.tsx— global error boundary. Required to be a client component by Next.js.not-found.tsx— custom 404 page. Server component.layout.tsx— root layout. Wraps everything inSessionProviderandToastProvider.globals.css— Tailwind v4@theme{}design token definitions and base resets.
components/
All reusable UI split into four sub-directories:
auth/— form components for each auth page (LoginForm, RegisterForm, etc.)nav/— Navbar, MobileMenu, NavLinks, ThemeTogglefooter/— Footer componentui/— primitive components: Button, Input, Modal, Loader, Toast
All components follow the same rule: colors from CSS variables only, no hardcoded values.
hooks/
useToast.tsx — the only custom hook. Provides a React context + useReducer toast system. Export ToastProvider (wraps the app) and useToast() (used in components to fire toasts).
lib/
All non-component, non-action utilities:
auth.ts— NextAuth v5 configuration. Credentials + Google providers, JWT callbacks, session callbacks.db/— database client(s) for the chosen variant, plus Mongoose models.email.ts— Resend client +sendVerificationEmail()andsendPasswordResetEmail()functions.ratelimit.ts— Upstash Redis limiters.authRatelimit(5/min) andotpRatelimit(3/min).sanitize.ts—escapeHTML(),sanitizeString(),sanitizeObject(),stripMongoOperators(),sanitizeAndStrip().tokens.ts—generateOTP(),hashOTP(),verifyOTP(),OTP_EXPIRY_MINUTES.validate.ts— Zod schemas for all forms +parseSchema()helper.
proxy.ts
Next.js 16 middleware — renamed from the legacy middleware.ts. Exports a proxy() function (not middleware()).
Handles two concerns:
- Route protection — unauthenticated requests to protected routes redirect to
/login. Authenticated requests to auth routes (login/register) redirect to/dashboard. - Security headers — applied to every response: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, HSTS (production only).
Do not rely on proxy.ts as your only auth gate
proxy.ts is a first-line redirect layer only. Every server action and server component re-checks the session independently via auth().types/
Two files:
index.ts— shared types: User, Session, NavLink, ActionState, OTPPurpose, ToastItem, ButtonVariant, LoaderVariant.next-auth.d.ts— module augmentation that addsid,role, andemailVerifiedto NextAuth'sSessionandJWTtypes.
setup.mjs
The interactive database setup script. Run once after cloning. Written as an ES module (.mjs) so it runs with plain node without TypeScript compilation.
After running, it deletes itself. The final project has no trace of the scaffold setup process.