Every time I started a new Next.js project, I lost the first week to setup.
Authentication. Internationalization. Role-based access. SEO meta tags. Environment validation. Error monitoring. Linting. Testing. CI pipelines.
By the time I had a working foundation, the excitement was gone, buried under config files and boilerplate glue code.
After doing this across multiple SaaS projects, I stopped and asked myself: What if I built the foundation once, properly, and never had to do it again?
So I did. Then I rebuilt it from scratch with a feature-sliced architecture and a clearer frontend-first scope.
The result is Nextjs-Elite-Boilerplate (v0.3.0): a production-ready, frontend-first Next.js 16 starter that's MIT-licensed and open source.
๐ Live Demo ยท ๐ฆ GitHub Repo ยท ๐ Use This Template ยท Deploy on Vercel
Table of Contents
- Why Another Boilerplate?
- What Makes This One Different
- Honest Caveats (So You Know What You're Getting)
- The Full Feature Breakdown
- Lighthouse? All 100s.
- Getting Started in 5 Minutes
- Production Checklist
- The Project Structure (For Humans)
- Everything You Get Out of the Box
- Who Should Use This (and Who Shouldn't)
- Contributing
- Final Thoughts
Why Another Boilerplate?
I know what you're thinking. The world doesn't need another Next.js starter.
Honestly? Most of the time, you'd be right. Most starters fall into two camps:
-
Too bare. A
create-next-appwith a theme toggle and a "TODO: add auth here" comment. - Too opinionated. Ships with a Prisma schema, a specific database, and an ORM you didn't ask for, tightly coupling you to decisions you haven't made yet.
I wanted something in between: a frontend-first foundation that handles auth, roles, i18n, SEO, forms, data fetching, error monitoring, and developer tooling, but doesn't force a database on you. You bring your own API (REST, GraphQL, BFF, whatever), and this boilerplate handles everything else.
That's what Next.js Elite is. And it's free, MIT-licensed, and open source.
What Makes This One Different
Here's what you get with a single git clone:
- Next.js 16 + React 19 with App Router and Server Components
- BetterAuth with email/password and optional Google OAuth
-
Permission-based RBAC using parallel routes (
@admin,@user) - Type-safe i18n via next-intl: 6 languages, RTL, cookie-based locale, compile-time checked keys
- T3 Env for Zod-validated environment variables (server + client split)
-
TanStack Query + ofetch (
apiFetch) for API data fetching with Zod response parsing - React Hook Form + Zod for forms with shared validation schemas
- Sentry for error monitoring, pino for server logging
- Optional Upstash helpers for rate limiting (when env vars are set)
- Vitest + Playwright for unit and E2E testing
- Lefthook + Commitlint + Knip for automated code quality
- One JSON file drives SEO, sitemap, robots.txt, and manifest config
- Demo mode for instant previews on the login page
-
Docker + Vercel deployment ready (
output: 'standalone')
And the Lighthouse scores? Well...
Honest Caveats (So You Know What You're Getting)
The homepage hero cards describe what ships today. These six caveats match those cards and what the repo actually does โ no overselling.
Modern stack, lean setup โ API-driven by design: no ORM or database layer. The example
usersclient expects your/api/usersor an external API; no mock DB is included.BetterAuth โ Auth works out of the box for local and demo use. For multi-instance production, configure a Better Auth storage adapter so sessions persist across instances (BetterAuth defaults are not shared across nodes).
Parallel routing โ
@user/@adminslots share/dashboard, but permissions are starter-grade RBAC (two roles, email allowlist for admin). Extend roles in your backend when you need multi-tenant or org-level access.Type-safe i18n โ Locale lives in a cookie (
NEXT_LOCALE; no/enor/frURL prefixes): simpler UX, not path-prefixed locales for multilingual SEO.SEO + PWA, server-first โ Metadata, sitemap, robots, and JSON-LD come from
site.config.json. Replace placeholder org/domain values before you ship.Developer experience โ CI runs typecheck โ lint โ knip โ test โ build. Test coverage is starter-level (RBAC/i18n unit tests + light E2E). Optional
getRateLimiter()exists insrc/libs/rate-limit.tsbut is not wired to auth or API routes by default.
Lighthouse? All 100s.
This isn't just "good enough for a starter." The boilerplate scores 100 across all four Lighthouse categories: Performance, Accessibility, Best Practices, and SEO, right out of the box.
No tricks. No deferred audits. That's the production build, tested against the live demo at nextjs-elite-boilerplate.vercel.app.
Most boilerplates treat performance as an afterthought. Here, it's baked in from day one: server components by default, client components only where needed, semantic HTML, proper heading hierarchy, and optimized asset loading.
The Full Feature Breakdown
Let's walk through every major system. I'll cover what it does, why I chose it, and how it works in this codebase.
Authentication: BetterAuth
Auth is built on BetterAuth, exposed at /api/auth/* via src/app/api/auth/[...all]/route.ts.
Here's what you get:
- Email/password sign-up and login โ works immediately
-
Google OAuth โ set
GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRETandNEXT_PUBLIC_GOOGLE_AUTH_ENABLED=true -
Server-side session reads โ
getCurrentUser()in Server Components; client usesauthClient.useSession()via the auth provider -
Admin role mapping โ comma-separated emails in
AUTH_ADMIN_EMAILS/NEXT_PUBLIC_AUTH_ADMIN_EMAILS
Sessions use BetterAuth's default storage. For production on multiple instances, plug in a database or Redis adapter โ see the BetterAuth docs.
Demo mode lives in src/features/auth/demo/. With NEXT_PUBLIC_DEMO_MODE=true, the login page shows click-to-fill credentials and auto-registers seed accounts on first sign-in:
| Role | Password | |
|---|---|---|
| User | user@test.com |
12345678 |
| Admin | admin@test.com |
12345678 |
Going to production? Set the flag to false, or delete the demo/ folder. Nothing else imports it except the login flow.
RBAC: Permissions, Not Just Roles
Most boilerplates give you if (role === 'admin') checks scattered across your code. That doesn't scale.
Next.js Elite uses permission-based RBAC. Each role maps to permissions; pages check permissions, not raw role strings:
import { requirePermission } from '@/features/auth/rbac/require';
const AdminDashboardPage = async () => {
const user = await requirePermission('dashboard.view:admin');
return <h1>Welcome back, {user.email}</h1>;
};
Invalid sessions redirect to /login. Insufficient permissions redirect to /unauthorized.
The routing layer uses Next.js parallel routes:
src/app/(protected)/
@admin/dashboard/ โ Admin sees this
@user/dashboard/ โ Regular users see this
layout.tsx โ Picks the right slot based on permissions
Today there are two roles (user, admin) and two dashboard permissions. Admin is granted via email allowlist, not a database role table โ extend rbac/roles.ts and your backend when you outgrow that.
Internationalization: next-intl with Type Safety
The boilerplate uses next-intl with:
-
Cookie-based locale (
NEXT_LOCALE) โ no/en/or/fr/URL prefixes - 6 languages out of the box: English, เฆฌเฆพเฆเฆฒเฆพ, ุงูุนุฑุจูุฉ (full RTL), Franรงais, Espaรฑol, ็ฎไฝไธญๆ
-
Compile-time type checking โ
t("navigation.home")autocompletes; typos fail the build
Translation files live in messages/. Add a language in site.config.json, create messages/<locale>.json, and the runtime picks it up.
SEO: One Config File
SEO is driven by src/features/site/site.config.json, validated with Zod in src/features/site/config.ts.
That one file drives:
- Open Graph and Twitter Card meta tags
- JSON-LD structured data (
Organization,WebSite,SoftwareApplication) - Dynamic sitemap and robots.txt
- PWA web app manifest
- Canonical URLs and theme colors
{
"appName": "My SaaS",
"domain": "https://mysaas.com",
"title": "My SaaS โ Do X Better",
"description": "We help Y achieve Z.",
"organization": {
"name": "My Company",
"url": "https://mysaas.com"
},
"images": { "og": "/og-image.webp" }
}
Data Fetching: ofetch + TanStack Query
The API layer uses ofetch via apiFetch in src/libs/api-client.ts (defaults to same-origin /api) and TanStack Query on the client.
The users feature is a copy-paste pattern โ you implement /api/users or point NEXT_PUBLIC_APP_URL at your backend:
import { useUsers } from '@/features/users/hooks/use-users';
const { data, isLoading } = useUsers();
// src/features/users/api.ts
export async function getUsers(): Promise<User[]> {
return apiFetch('/users', { schema: userListSchema });
}
Forms: React Hook Form + Zod
Every auth form uses React Hook Form with Zod resolvers. Schemas live in src/features/auth/schemas/:
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { loginSchema, type LoginInput } from '@/features/auth/schemas/login';
const form = useForm<LoginInput>({
resolver: zodResolver(loginSchema),
defaultValues: { email: '', password: '' },
});
Environment Variables: T3 Env
@t3-oss/env-nextjs + Zod validates server and client env vars at build time. SKIP_ENV_VALIDATION=true is supported for CI and Docker builds. A missing BETTER_AUTH_SECRET in production logs a warning at runtime (placeholder only for local dev).
UI: shadcn/ui + Tailwind CSS v4
shadcn/ui (Radix + CVA + Tailwind v4). Components live in src/components/ui/ โ copy and own them.
Dark mode uses a lightweight custom theme provider in src/features/theme/ (system / light / dark) with a toggle in the header โ no next-themes dependency.
Observability: Sentry + pino + Rate Limiting
-
Sentry โ
src/instrumentation.ts(server) andsrc/instrumentation-client.ts(client). SetSENTRY_DSN/NEXT_PUBLIC_SENTRY_DSN. -
pino โ structured server logging in
src/libs/logger.ts. -
@upstash/ratelimit โ optional
getRateLimiter()/isRateLimited()insrc/libs/rate-limit.tswhenUPSTASH_REDIS_*is set. Wire it into your route handlers where you need protection.
Testing: Vitest + Playwright
-
Unit tests: Vitest + React Testing Library. Specs in
tests/(auth, i18n) and colocated*.test.tsxundersrc/components/ui/andsrc/libs/. -
E2E: Playwright in
e2e/โ home, health check, login page smoke tests. Runnpm run e2e(config:e2e/playwright.config.ts). -
CI:
.github/workflows/check.yml(typecheck โ lint โ knip โ test โ build) andplaywright.ymlfor E2E.
Developer Experience: The Full Pipeline
- Lefthook โ pre-commit lint/format, commit-msg Commitlint
- Knip โ unused files, exports, and dependencies
-
Renovate โ automated dependency updates (
.github/renovate.json) - ESLint 9 flat config + Prettier (Tailwind class sorting)
- Vercel Analytics โ included in the root layout
proxy.ts is a pass-through middleware placeholder โ auth and locale are handled in Server Components and next-intl request config, not at the edge.
Getting Started in 5 Minutes
Prerequisites: Node.js 20.9+, npm / pnpm / yarn / bun.
1. Clone and install
git clone https://github.com/salmanshahriar/Nextjs-Elite-Boilerplate.git
cd Nextjs-Elite-Boilerplate
npm install
2. Set up environment
cp .env.example .env
Key variables (see .env.example for the full list):
-
BETTER_AUTH_SECRETโ 32+ chars in production (openssl rand -base64 32) -
BETTER_AUTH_URLโ optional; auto-derived on Vercel -
NEXT_PUBLIC_GOOGLE_AUTH_ENABLED=true+ Google credentials for OAuth -
NEXT_PUBLIC_DEMO_MODE=truefor instant test accounts -
SKIP_ENV_VALIDATION=truefor CI/Docker when secrets aren't available yet
3. Brand it
Edit src/features/site/site.config.json โ app name, domain, SEO, social links, locales.
4. Add languages (optional)
Add the locale to site.config.json, create messages/<locale>.json.
5. Run
npm run dev
Open http://localhost:3000.
All available scripts
| Command | What it does |
|---|---|
npm run dev |
Dev server |
npm run build |
Production build |
npm run start |
Production server |
npm run analyze |
Bundle analysis (ANALYZE=true) |
npm run typecheck |
tsc --noEmit |
npm run lint |
ESLint + Prettier check |
npm run lint:fix |
Auto-fix lint + format |
npm run knip |
Dead code / dependency detection |
npm run check |
typecheck + lint + knip + test (CI gate) |
npm run test |
Vitest run (config/vitest.config.ts) |
npm run test:watch |
Vitest watch |
npm run e2e |
Playwright E2E |
npm run e2e:ui |
Playwright UI mode |
npm run e2e:webkit |
WebKit-only E2E |
Deploy
Vercel (one click):
Docker:
docker build -t nextjs-elite .
docker run --rm --env-file .env -p 3000:3000 nextjs-elite
# or: docker compose up --build
Production Checklist
Before you ship:
- Set a strong
BETTER_AUTH_SECRET(32+ characters). - Configure a Better Auth storage adapter for multi-instance deploys.
- Set
NEXT_PUBLIC_DEMO_MODE=falseor removesrc/features/auth/demo/. - Implement
/api/users(or your real API) for features that callapiFetch. - Update
site.config.jsonโ real domain, org, and OG image (not placeholders). - Optionally enable Sentry and Upstash rate limiting on sensitive routes.
The Project Structure (For Humans)
Feature-sliced architecture: each feature owns its components, hooks, schemas, and server logic. Cross-cutting infra lives in libs/.
.
โโโ .github/workflows/ check.yml + playwright.yml
โโโ config/ vitest.config.ts, vitest.setup.ts
โโโ e2e/ Playwright specs + playwright.config.ts
โโโ messages/ Translation files (en, bn, ar, fr, es, zh)
โโโ tests/ Vitest specs (auth, i18n)
โโโ proxy.ts Middleware (pass-through)
โโโ lefthook.yml Git hooks
โโโ knip.json Dead-code config
โโโ src/
โ โโโ app/ App Router
โ โ โโโ (auth)/ Login, register, password reset
โ โ โโโ (public)/ Marketing pages
โ โ โโโ (protected)/ Auth-gated area
โ โ โ โโโ @admin/ Admin dashboard slot
โ โ โ โโโ @user/ User dashboard slot
โ โ โ โโโ layout.tsx Permission-based slot picker
โ โ โโโ api/ BetterAuth + health
โ โ โโโ layout.tsx Root layout + SEO
โ โ โโโ providers.tsx Theme + Auth + Query
โ โโโ components/
โ โ โโโ shared/ Hero, logo, home sections
โ โ โโโ ui/ shadcn/ui primitives
โ โโโ features/
โ โ โโโ auth/ BetterAuth, RBAC, demo mode
โ โ โโโ i18n/ next-intl config
โ โ โโโ navigation/ Header + Sidebar
โ โ โโโ site/ site.config.json + Zod parser
โ โ โโโ theme/ Custom theme provider
โ โ โโโ users/ Example API + hooks
โ โโโ libs/ env, api-client, logger, rate-limit, utils
โโโ package.json scripts; Prettier + Commitlint config
Key conventions:
-
features/<name>/โ vertical slices -
libs/โ cross-cutting infra, no business logic -
components/ui/โ shadcn primitives; extend, don't fight the CLI -
schemas/โ shared Zod schemas (e.g. API responses)
Everything You Get Out of the Box
โ
Next.js 16 + React 19 (App Router, Server Components)
โ
TypeScript 5.9 (strict)
โ
Tailwind CSS v4
โ
BetterAuth (email/password + optional Google OAuth)
โ
Permission-based RBAC with parallel routes
โ
next-intl (6 languages, RTL, type-safe, cookie-based)
โ
T3 Env (Zod-validated server + client env vars)
โ
TanStack Query + ofetch (apiFetch + Zod parsing)
โ
React Hook Form + Zod (auth forms + shared schemas)
โ
SEO suite (OG, Twitter Cards, JSON-LD, sitemap, robots, manifest)
โ
Custom theme provider (light / dark / system)
โ
shadcn/ui (Radix + CVA + Tailwind)
โ
Sentry (server + client instrumentation)
โ
pino (structured server logging)
โ
Optional Upstash rate limiting helpers
โ
Vitest + React Testing Library
โ
Playwright E2E
โ
Lefthook + Commitlint
โ
Knip (dead-code hygiene)
โ
ESLint + Prettier
โ
GitHub Actions CI + Playwright workflow
โ
Docker + Docker Compose (standalone output)
โ
Demo mode (isolated src/features/auth/demo/)
โ
Health check (GET /api/health)
โ
Renovate + Vercel Analytics
โ
Vercel one-click deploy
Who Should Use This (and Who Shouldn't)
This is a good fit if you're building:
- A SaaS product with multiple user roles
- An internationalized app (especially with RTL requirements)
- A frontend that consumes an existing API or BFF
- A project where you want auth, RBAC, i18n, and DX tooling on day one without inheriting a database
Probably not the right choice for:
- A single-page landing site (more than you need)
- An app that needs a tightly-coupled database layer in the same repo (this is intentionally API-only)
- Enterprise RBAC with orgs, teams, and dynamic roles in the DB (start here, extend in your backend)
Contributing
The project is fully open source and contributions are welcome:
- Fork and branch from
main(feat/...,fix/...) - Run
npm run checkโ it must pass - Use Conventional Commits (Lefthook enforces this)
- Open a PR with a clear description
๐ Report a bug ยท โญ Star on GitHub ยท ๐ค Submit a PR
Final Thoughts
I built the first version because I was tired of repeating myself. Then I rebuilt it with feature-sliced folders, BetterAuth, type-safe env and i18n, parallel-route dashboards, and a DX pipeline (Lefthook, Knip, Vitest, Playwright) that matches what I actually run before every push.
The goal was never the biggest starter kit. It was the one I want on day one of a SaaS frontend โ and still trust on day one hundred, with a backend I chose myself.
If it saves you a week of glue code, it was worth open-sourcing.
What's your biggest pain point when starting a new Next.js project? Drop a comment โ I'm always looking for improvements that stay frontend-first.
Happy building. ๐
๐ Live Demo ยท ๐ฆ GitHub ยท ๐ Use Template ยท Deploy on Vercel



Top comments (0)