DEV Community

Cover image for I built an opensource production-ready NEXT.JS STARTER KIT!
Salman Shahriar
Salman Shahriar

Posted on

I built an opensource production-ready NEXT.JS STARTER KIT!

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 configuration files and boilerplate glue code.

I kept rebuilding the same foundation across SaaS projects, so I stopped and built it once: Next Elite.

It is a frontend-first Next.js 16 + React 19 boilerplate designed to consume APIs (REST/GraphQL/BFF) instead of owning a database, allowing you to drop it on top of any backend you already have. It is feature-based, optimized for speed, SEO, and developer productivity, and includes 40+ custom and reusable UI components built on shadcn/ui. It is 100% open source under the MIT license.

Live Demo · GitHub Repo · Use This Template · Deploy on Vercel

Next.js Elite production-ready SaaS boilerplate cover

TL;DR: git clone, npm install, cp .env.example .env, npm run dev. Open http://localhost:6767. You get auth, RBAC dashboards, 6-language i18n, 40+ UI components, SEO, forms, testing, and CI. Try the demo.


Table of Contents

  1. Why Another Next.js Boilerplate? (The Concept)
  2. What's Inside: The Next Elite Stack & Features
  3. Lighthouse Score: 100% Performance & SEO
  4. Quick Start: Launch Your Project in 60 Seconds
  5. Deep Dive: How Next Elite Works Under the Hood
  6. Clean Feature-Based Directory Structure
  7. Configuration & Environment Variables
  8. Development, Testing & CI/CD
  9. Architectural Caveats: What Next Elite is NOT
  10. Production Checklist: Going Live
  11. Contributing & Open Source

1. Why Another Next.js Boilerplate? (The Concept)

Most Next.js starters on GitHub are either too bare (providing just a dark mode toggle and a "TODO: add auth" comment) or too bloated (bundling Prisma, PostgreSQL, Docker Compose, stripe webhooks, and an ORM tightly coupled to their own DB schema).

If you already have a backend (written in Go, Python, Laravel, or Node.js) or want to build a backend-for-frontend (BFF) architecture, tearing out the built-in database layer from a boilerplate is painful.

Next Elite sits in the sweet spot. It handles the complex frontend foundation, UI components, role management, and locale settings while leaving the database and API fetching structure flexible. It's built to consume APIs directly, allowing you to drop it on top of any backend you already have.

When to use Next Elite

Next Elite is best for:

  • SaaS apps with multiple user roles.
  • Multi-lingual/Internationalized products (LTR + RTL).
  • Frontends consuming an existing backend or BFF.
  • Projects requiring a clean, feature-based modular structure.

It is probably overkill for:

  • Single-page landing sites.
  • Apps that need a tightly-coupled DB layer (API-only design).

2. What's Inside: The Next Elite Stack & Features

Here is the clean, high-performance tech stack built into Next Elite, broken down by core categories:

Frameworks & Core

  • Next.js 16 (App Router) - Fast, modern React framework with full support for React 19 features (Server/Client components, Server Actions).
  • TypeScript 6 - End-to-end type safety for rock-solid refactoring and developer experience.
  • Node.js 22 - Built on the latest LTS runtime (22.12+ required).
  • Feature-Based Architecture - Structured around self-contained vertical slices/feature folders under src/features/ for maximum modularity and clean separation of concerns.

Authentication & Access Control

  • BetterAuth - Out-of-the-box email/password and OAuth (Google) authentication using /api/auth/* route handlers. Configure admin emails via AUTH_ADMIN_EMAILS or NEXT_PUBLIC_AUTH_ADMIN_EMAILS.
  • Role-Based Access Control (RBAC) - Flexible RBAC (user and admin roles) with server-side guards (requireUser, requirePermission) and parallel route slots (@admin, @user) for role-agnostic routing.

Internationalization (i18n)

  • next-intl - Type-safe, cookie-based localizations (no URL prefix) with support for English, বাংলা, العربية (RTL), Français, Español, and 简体中文. Translation keys are type-checked (t("key") works; typos fail compile-time).

UI & Styling

  • Tailwind CSS 4 - Utility-first styling with @tailwindcss/postcss and tw-animate-css.
  • shadcn/ui - Highly customizable UI components built with Tailwind CSS, Radix UI, and CVA. Includes a live /ui-components showcase page.

    Next Elite UI Components
  • Theme Support - Easy light/dark mode transitions via theme toggle.

API & Data Fetching

  • TanStack Query (React Query) - Pre-configured QueryClientProvider in src/app/providers.tsx with sensible defaults (staleTime, gcTime, retry). Ready to wire useQuery / useMutation hooks to your REST, GraphQL, or BFF endpoints.

Observability & Infrastructure

  • Sentry Integration - Complete error tracking and performance instrumentation for client and server.
  • Health Probes - Direct GET /api/health endpoint for load balancers.

Quality Gates & Tooling

  • Testing Suite - Unit/component testing with Vitest and React Testing Library, and E2E testing with Playwright.
  • Hygiene & Linting - Oxlint and Oxfmt for fast linting and formatting, plus Knip for dead code/dependency hygiene.
  • Git Hook Automation - Lefthook pre-commit hooks (oxlint + oxfmt) and Commitlint to maintain codebase quality.

3. Lighthouse Score: 100% Performance & SEO

One of the key goals of Next Elite was achieving flawless performance and SEO defaults. Out-of-the-box, the production build scores a perfect 100 across the board on Lighthouse:

Next Elite Lighthouse Report - 100 Performance, Accessibility, Best Practices, and SEO

This is achieved by rendering Server Components by default, minimizing client-side javascript, optimizing images, and dynamically serving optimized SEO meta tags from a single configuration file.


4. Quick Start: Launch Your Project in 60 Seconds

One-click Deploy

Deploy this template to Vercel with one click:

Deploy with Vercel

Set the environment variables from .env.example in your Vercel project (Production + Preview).

Prerequisites

  • Node.js 22.12 or later
  • npm

Local Setup

  1. Clone the repository and navigate into it:
   git clone https://github.com/salmanshahriar/Next-Elite.git
   cd Next-Elite
Enter fullscreen mode Exit fullscreen mode
  1. Install dependencies:
   npm install
Enter fullscreen mode Exit fullscreen mode
  1. Set up your environment variables:
   cp .env.example .env
Enter fullscreen mode Exit fullscreen mode
  1. Start the development server:
   npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:6767 to view your local instance.

Demo Credentials

When NEXT_PUBLIC_DEMO_MODE=true is enabled, the login screen includes a quick-fill panel with these seed credentials:

Role Email Password
User user@test.com 12345678
Admin admin@test.com 12345678

[!NOTE]
For production deployments, set NEXT_PUBLIC_DEMO_MODE=false or remove the self-contained src/features/auth/demo/ module.

Docker Setup

Run the application locally via Docker:

cp .env.example .env
docker build -t next-elite .
docker run --rm --env-file .env -p 6767:6767 next-elite
Enter fullscreen mode Exit fullscreen mode

Or using Docker Compose:

docker compose up --build
Enter fullscreen mode Exit fullscreen mode

The Dockerfile uses Next.js standalone output with a built-in health check against /api/health.

Multi-Arch Deploy (ARM64 + AMD64)

The Dockerfile produces images that run on both linux/amd64 and linux/arm64. Build a multi-arch image with Buildx:

docker buildx create --name multiarch --use   # one-time setup
docker buildx build --platform linux/amd64,linux/arm64 -t next-elite .
Enter fullscreen mode Exit fullscreen mode

This is ideal for self-hosting on ARM servers (Oracle Cloud, Raspberry Pi, etc.).

Dokploy Deployment

This template is ready for Dokploy - the open-source PaaS.

  1. Create a new Application in Dokploy and point it to your fork of this repo.
  2. Set the build type to Dockerfile (auto-detected).
  3. Configure environment variables via the Dokploy UI (see .env.example for the full list).
  4. Deploy - Dokploy automatically builds and runs the container with health checks.

The included HEALTHCHECK instruction pings /api/health so Dokploy can monitor and restart the container if it becomes unresponsive.

View Available Scripts & CLI Commands

Command Description
npm run dev Start the dev server (port 6767)
npm run build Production build
npm run start Start the production server
npm run analyze Build with @next/bundle-analyzer
npm run check CI gate: typecheck + lint + knip + tests
npm run lint:fix Auto-fix with Oxlint + Oxfmt
npm run test:watch Vitest watch mode
npm run playwright:install Download Playwright browsers
npm run playwright:install:deps Install OS libs for browsers (Linux)
npm run e2e Playwright E2E
npm run e2e:ui Playwright UI mode
npm run e2e:webkit Playwright WebKit only

5. Deep Dive: How Next Elite Works Under the Hood

How a request flows:

  1. User opens a page - the Server Component renders first.
  2. Auth + role check - requireUser() / requirePermission() read the BetterAuth session and redirect to /login or /unauthorized if needed.
  3. HTML is sent to the browser; translations come from messages/ via next-intl.
  4. Live data (lists, forms, etc.) is fetched on the client with TanStack Query → your API (REST/GraphQL/BFF).

Type-Safe RBAC & BetterAuth

Permissions are checked on the server, not with scattered if (role === 'admin') checks.

View Auth & RBAC Usage

// Server Component example
import { requirePermission } from '@/features/auth/rbac/require';
import { getTranslations } from 'next-intl/server';

const AdminDashboardPage = async () => {
  const [, t] = await Promise.all([
    requirePermission('dashboard.view:admin'),
    getTranslations('dashboard.admin'),
  ]);
  return <h1>{t('title')}</h1>;
};

export default AdminDashboardPage;
Enter fullscreen mode Exit fullscreen mode

Next Elite utilizes Next.js Parallel Routes to clean up role-agnostic layouts. The routing structure mounts specific slots based on the user's role:

src/app/(protected)/
  ├── @admin/dashboard/     # Admin dashboard slot
  ├── @user/dashboard/      # User dashboard slot
  └── layout.tsx            # Picks slot based on permissions
Enter fullscreen mode Exit fullscreen mode

Adding a Role

  1. Append the role to the UserRole union in src/features/auth/rbac/permissions.ts.
  2. Map permissions for the role in src/features/auth/rbac/roles.ts.
  3. Optional: add a parallel route slot - src/app/(protected)/@/... - and update (protected)/layout.tsx to render it based on permissions.

Zero-Prefix cookie-based i18n

Unlike standard i18n configurations that force prefixes like /en/ or /es/ in the URL (which can clutter routes and create duplicate routing configurations), Next Elite implements zero-prefix cookie-based locales.

Adding a Language

  1. Add the locale code to languages.supported in site.config.json and add an entry under languages.locales.
  2. Create messages/.json mirroring messages/en.json.
  3. The next-intl runtime picks it up automatically; types update from src/global.d.ts.

Site & SEO Configuration

src/features/site/site.config.json is the single source of truth for SEO metadata, dynamic sitemaps, localized routes, and PWA manifest:

{
  "appName": "Next Elite",
  "domain": "https://yourdomain.com",
  "tagline": "Frontend-first, API-driven, batteries included.",
  "title": "Next Elite - Production-Ready SaaS Boilerplate",
  "description": "Frontend-first Next.js 16 + React 19 boilerplate with i18n, RBAC and BetterAuth."
}
Enter fullscreen mode Exit fullscreen mode

View Forms Usage (React Hook Form + Zod)

'use client';

import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { loginSchema, type LoginInput } from '@/features/auth/schemas/login';

const form = useForm({
  resolver: zodResolver(loginSchema),
  defaultValues: { email: '', password: '' },
});
Enter fullscreen mode Exit fullscreen mode

6. Clean Feature-Based Directory Structure

Next Elite uses a Feature-Based (Vertical Slice) Architecture under src/features/. Each folder contains its own components, hooks, schemas, and config. Shared utilities live under src/libs/ or src/components/shared/.

View Directory Structure

.
├── .github/
│   ├── workflows/            CI: check.yml + playwright.yml
│   └── renovate.json         Dependency updates
├── config/                   vitest.config.ts, vitest.setup.ts
├── e2e/                      Playwright specs + playwright.config.ts
├── messages/                 next-intl translations (en, bn, ar, fr, es, zh)
├── public/                   Static assets
├── tests/                    Vitest specs (auth, i18n)
├── components.json           shadcn/ui CLI config
├── .oxlintrc.json            Oxlint rules (Next.js, TypeScript, React, Unicorn)
├── .oxfmtrc.json             Oxfmt formatter config (Tailwind class sorting)
├── knip.json
├── next.config.mjs
├── package.json              scripts + Commitlint config
├── package-lock.json         npm lockfile (single source of truth)
├── proxy.ts                  Next.js 16 network proxy (pass-through)
├── tsconfig.json
├── lefthook.yml              Git hooks (pre-commit, commit-msg)
├── src/
│   ├── app/                  App Router
│   │   ├── (auth)/           Login &amp; auth pages
│   │   ├── (public)/         Marketing pages (home, ui-components)
│   │   ├── (protected)/      Authenticated area + RBAC
│   │   │   ├── @admin/       Admin dashboard slot
│   │   │   ├── @user/        User dashboard slot
│   │   │   └── layout.tsx    Picks slot based on permissions
│   │   ├── api/              Route handlers (BetterAuth, health)
│   │   ├── layout.tsx        Root layout, SEO, providers
│   │   ├── providers.tsx     Theme + Auth + TanStack Query
│   │   ├── manifest.ts       Web app manifest
│   │   ├── robots.ts         robots.txt
│   │   └── sitemap.ts        Dynamic sitemap
│   ├── components/
│   │   ├── shared/           App-level shared components
│   │   ├── icons/            Icon components
│   │   └── ui/               shadcn/ui primitives
│   ├── features/             Feature modules (vertical slices)
│   │   ├── auth/             BetterAuth + RBAC
│   │   │   ├── lib/          auth + auth-client (BetterAuth singletons)
│   │   │   ├── server/       Server-only helpers (getCurrentUser)
│   │   │   ├── hooks/        Auth provider + useAuth hook
│   │   │   ├── components/   Login form, register form
│   │   │   ├── demo/         Self-contained demo module (delete for prod)
│   │   │   ├── rbac/         permissions, roles, can, require
│   │   │   └── schemas/      Zod login + register schemas
│   │   ├── i18n/             next-intl config (routing, request, actions)
│   │   ├── navigation/       Header, sidebar, topbar, top loader
│   │   ├── site/             siteConfig + locale utilities
│   │   └── theme/            Theme provider + toggle
│   ├── hooks/                Cross-feature hooks (use-scroll)
│   ├── libs/                 Cross-cutting infra (env, query-client, utils)
│   ├── instrumentation.ts    Server Sentry init
│   ├── instrumentation-client.ts  Client Sentry init
│   └── global.d.ts           next-intl type augmentation
└── ...
Enter fullscreen mode Exit fullscreen mode

7. Configuration & Environment Variables

Every variable is documented in .env.example and validated by src/libs/env.ts (T3 Env).

  • BETTER_AUTH_URL is optional - derived from VERCEL_URL in production, http://localhost:6767 locally.
  • BETTER_AUTH_SECRET (32+ chars) must be set at runtime in production. A missing secret logs a warning instead of crashing the build.
  • Set SKIP_ENV_VALIDATION=true in CI / Docker build steps when env vars aren't available yet.

Key variables:

Variable Purpose
BETTER_AUTH_SECRET Auth signing secret (32+ chars)
GOOGLE_CLIENT_ID/SECRET Optional Google OAuth
NEXT_PUBLIC_GOOGLE_AUTH_ENABLED Show Google sign-in button
AUTH_ADMIN_EMAILS Comma-separated admin role emails
NEXT_PUBLIC_DEMO_MODE Demo credentials panel (disable for prod)
SENTRY_DSN / NEXT_PUBLIC_SENTRY_DSN Optional Sentry error tracking
NEXT_PUBLIC_APP_URL Public app URL (SEO/OAuth)

8. Development, Testing & CI/CD

Editor Setup

Install the Oxc VS Code extension (oxc.oxc-vscode) for format-on-save and Oxlint fix-on-save. Project settings in .vscode/settings.json are preconfigured.

Testing

  • Unit / component: Vitest + React Testing Library (config/vitest.config.ts). Use renderWithProviders from @tests/utils/render for components that need app context (i18n, theme, auth, React Query). Plain render is fine for isolated UI primitives.
  • End-to-end: Playwright in e2e/ on port 6767 (127.0.0.1). Local runs use next dev (all browsers); CI uses production next start (Chromium only). Run playwright:install before the first E2E run; on Linux, WebKit needs playwright:install:deps (sudo). Stop npm run dev before npm run e2e - E2E starts its own server.

CI/CD Pipeline

  • .github/workflows/check.yml - typecheck → lint → knip → unit tests → build, on every push and PR.
  • .github/workflows/playwright.yml - build → Playwright E2E (Chromium, production server).
  • .github/renovate.json - groups non-major dependency updates and automerges patches.

9. Architectural Caveats: What Next Elite is NOT

To keep the boilerplate clean and adaptable, I made specific design trade-offs:

  1. No Database Bundled: There is no Prisma, Drizzle, Postgres, or MongoDB setup. Next Elite is built to communicate with an external API. BetterAuth runs without a database adapter out of the box.
  2. Simple RBAC System: The starter RBAC covers two roles (user and admin) with a fast-path admin list via environment variables. For complex multi-tenant permissions, map roles on your main database and API layer.
  3. Cookie-Based i18n: By storing user localization choice in a cookie rather than a path-prefix (like /en/dashboard), routes remain simpler, but path-prefixed SEO indexing for multiple locales will require a custom router setup.
  4. Local BetterAuth Sessions: By default, session keys run locally. A session adapter is recommended for production setups using multiple server instances.

10. Production Checklist: Going Live

Before deploying Next Elite to production, run through these essential configuration steps:

  1. Configure Auth Secrets: Set BETTER_AUTH_SECRET (at least 32 characters long) in your hosting dashboard.
  2. Add a Session Storage Adapter: BetterAuth requires an external database or Redis adapter to manage server sessions in multi-instance production environments.
  3. Disable Demo Mode: Set NEXT_PUBLIC_DEMO_MODE=false or completely delete the src/features/auth/demo/ folder.
  4. Link Your API: Point NEXT_PUBLIC_APP_URL at your live domain and wire TanStack Query hooks to your REST/GraphQL/BFF service.
  5. Update SEO Metadata: Change src/features/site/site.config.json with your project domain, official OG image, and app description.
  6. Enable Error Tracking: Set SENTRY_DSN and NEXT_PUBLIC_SENTRY_DSN to activate Sentry instrumentation.
  7. Set SKIP_ENV_VALIDATION=true in CI/Docker build steps when env vars aren't available at build time.

11. Contributing & Open Source

Next Elite is free and open-source under the MIT license. Contributions, bug reports, and discussions are welcome!

  1. Fork & branch from main (feat/..., fix/..., etc.)
  2. Ensure npm run check passes locally.
  3. Use Conventional Commits.
  4. Open a pull request.

If this boilerplate saved you time, a star helps more devs discover it

Live Demo · GitHub Repo · Use Template · Deploy on Vercel

Top comments (0)