Next.jsReactAdmin dashboardSaaSStarter

next-boilerplate — Next.js Admin dashboard Template

By uday-a

A SaaS admin starter template built on the Next.js App Router, with GitHub OAuth, magic-link sign-in, Polar billing, Drizzle with Postgres, an RBAC admin area, team invites, API keys, audit log, next-intl localization, and dashboard pages including charts, kanban and data table. All external integrations are enabled via environment variables.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

2 previews
Desktop homepage1 / 2
Desktop captureTop of page

Actual screenshot captured by the server browser.

All pages & views 2

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-10-03View source

What stands out

A quick read of the recorded project description.

01

Built-in GitHub OAuth and magic-link sign-in, with sessions stored in iron-session encrypted cookies

02

Polar billing integration: checkout, customer portal and signature-verified subscription webhooks

03

Drizzle ORM with Postgres data layer, including tables for users, projects, subscriptions, API keys, audit log and invites

04

Server-side RBAC with admin/editor/user roles and /admin/users and /admin/roles pages

05

Dashboard includes KPIs, ECharts charts, Leaflet map, kanban, TanStack data table and calendar

06

next-intl internationalization supports English and Spanish, with language switching via cookie

Template Details

This template is a Next.js starter kit for SaaS admin scenarios, using the App Router, React, TypeScript and Tailwind CSS, with UI components from the shadcn/ui-compatible @uipkge-react registry. The repository provides a complete route structure for login, pricing, terms, dashboard, settings and admin, and includes a demo mode: enabled by default in local development, it lets you enter the admin area via "Continue as demo user" without a database, OAuth app or API keys.

Functionally it covers authentication, billing, database, permissions and internationalization. Authentication supports GitHub OAuth and passwordless magic links, with sessions stored in encrypted cookies; billing integrates Polar checkout, customer portal and signature-verified subscription webhooks; the database uses Drizzle ORM with Postgres and includes tables for users, projects, subscriptions, API keys, audit log and invites; the admin area enforces admin/editor/user roles via server-side requireRole and provides user list and permission matrix pages; internationalization is based on next-intl, with English and Spanish built in and language switching via cookie.

Limitations to note: the MFA page and onboarding stepper are UI only and not enforced; the permission matrix page uses mock data and is session-only; the verifyApiKey helper for API keys is provided but not wired into any route; Sentry environment variables are validated but the SDK is not installed or integrated; GitHub is the only connected OAuth provider. Demo mode must be explicitly enabled via environment variables in deployed environments, and the demo session has admin privileges.

Next.jsReactAdminSaaSStarter

Is it right for your project?

Use Cases

  • SaaS product prototypes that need sign-in, billing and an admin interface
  • Quickly previewing admin features in demo mode without configuring a database or third-party keys
  • Projects that need a basic account system with team invites, API keys and audit log
  • Scenarios that need a multilingual admin interface and want to integrate external services incrementally via environment variables

Suitable For

  • Frontend or full-stack developers familiar with the Next.js App Router and TypeScript
  • Teams that need to quickly scaffold a SaaS admin skeleton and replace business logic themselves
  • Developers looking for reference implementations of Drizzle with Postgres and Polar billing integration

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    After cloning the repository, run npm install and create .env with AUTH_SECRET (generate with openssl rand -base64 32), then start with npm run dev.

  2. 2

    Demo mode is enabled by default in local development, and /login allows "Continue as demo user"; in deployed environments, explicitly set DEMO_MODE and NEXT_PUBLIC_DEMO_MODE to control whether it is enabled.

  3. 3

    To connect a database, configure DATABASE_URL and use npm run db:generate and npm run db:migrate to generate and run migrations.

  4. 4

    Integrations such as GitHub OAuth, Polar, Resend, Axiom and PostHog are enabled via environment variables; when not configured, the corresponding features degrade or log to standard output.

  5. 5

    The demo session has admin privileges; enable demo mode only when a public demo is explicitly required.

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This entry covers the free version of the public repository under the MIT license; the free scope is the code of this version and does not imply that external services or third-party assets are free.

Must comply with when using

  • You may use, modify, commercialize and distribute the code of this version for free.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the full MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • Demo mode sign-in creates a session with admin privileges; enable it only in deployments that explicitly require a public demo, otherwise keep it off.
  • The MFA page and onboarding stepper are UI only and not enforced; they cannot be used as real security or process controls.
  • The API key verification helper is not wired into any route, so API keys cannot currently be used for actual endpoint authentication.
  • The permission matrix page uses mock data and is session-only; it does not represent real persisted permission configuration.
  • Sentry environment variables are validated, but the SDK is neither installed nor integrated, so error monitoring is not actually available.
  • Only GitHub OAuth is connected; other OAuth providers are not implemented, and sign-in options are limited accordingly.
  • Magic-link sign-in requires DATABASE_URL to be configured; without Resend configured, emails are only output to standard output and are not actually sent.
  • When Polar-related environment variables are not configured, billing routes return errors and checkout and subscription features are unavailable.
  • Rate limiting is implemented in-memory per instance and has no global effect in multi-instance deployments; you need to replace it with shared storage.
  • Demo images, fonts, icons and other third-party assets must be checked against their respective licenses; the MIT license of the code alone is not sufficient to judge them.
  • External services such as domains, hosting, databases, payments or AI may incur separate charges.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

Demo sessions are **admin**, so only enable it where that's intended.

Original README

MFA and the onboarding stepper are UI screens, not enforced flows.

Original README

A `verifyApiKey()` helper is included but not yet wired into any route

Original README

permission-matrix UI (owner / admin / editor / viewer / billing) backed by mock data, session-only

Original README

env vars are validated in `lib/env.ts`, but the Sentry SDK is **not installed or wired** yet

Original README

GitHub is the only wired OAuth provider

Original README

Needs `DATABASE_URL` (Resend optional — the link is logged to stdout without it)

Original README

Billing routes return an instructive error

Original README

rate limits are in-memory per instance — swap in a shared store if you need global limits

Original README
https://github.com/uday-a/next-boilerplate/blob/main/LICENSEhttps://github.com/uday-a/next-boilerplate/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-03. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
More documented · 92 / 100
Technologies
Next.js · React
Website type
Admin dashboard · SaaS · Starter
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-10-03
Screenshot last checked
2026-10-03

A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.

The catalog identifies Next.js as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Review declaration: [email protected] · 2026-10-04

Inspect the recorded source material

SHA-256: 77c1b42143654e7fa7446ddfa9b753a204676651672b077d00ad20577723d30f

2026-10-03T15:02:44.147Z

Source file / repository
# Next.js 16 SaaS Boilerplate — React 19, TypeScript, Tailwind CSS 4

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
![Next.js 16](https://img.shields.io/badge/Next.js-16-black?logo=next.js)
![React 19](https://img.shields.io/badge/React-19-149eca?logo=react)
![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?logo=typescript&logoColor=white)
![Tailwind CSS 4](https://img.shields.io/badge/Tailwind_CSS-4-38bdf8?logo=tailwindcss&logoColor=white)
![Node 22+](https://img.shields.io/badge/node-%3E%3D22-339933?logo=node.js&logoColor=white)

A production-grade **Next.js 16 SaaS boilerplate / starter kit** (App Router) with **React 19, TypeScript and Tailwind CSS 4**, built on the shadcn/ui-compatible [**`@uipkge-react`**](https://uipkge.dev/react/components) UI registry. It ships GitHub OAuth + magic-link authentication, Polar billing, a Drizzle ORM + Postgres schema, an admin area with role-based access control (RBAC), team invites, API keys, an audit log, i18n with next-intl, and a full dashboard (charts, kanban, data table, calendar). **Every external integration is gated on env**, so a fresh clone runs in demo mode with no database, OAuth app or API keys.

**[Live demo](https://next-boilerplate-sooty.vercel.app/login)** · **[Vue/Nuxt sibling: nuxt-boilerplate](https://github.com/uday-a/nuxt-boilerplate)** · **[UI registry: uipkge.dev](https://uipkge.dev)**

- **Auth:** GitHub OAuth, passwordless magic links, demo sign-in, encrypted `iron-session` cookies, team invites by token
- **Billing:** Polar checkout, customer portal and signature-verified subscription webhooks
- **Database:** Drizzle ORM + Postgres — users, projects, subscriptions, API keys, audit log, invites
- **Admin & RBAC:** `admin` / `editor` / `user` roles enforced server-side, admin user list, permission-matrix UI
- **Dashboard:** KPIs, ECharts charts, Leaflet map, kanban, TanStack data table, calendar, messages, activity heatmap
- **i18n:** next-intl (English + Spanish), cookie-based locale, optional over-the-air translations
- **DX:** zod-validated env, typed API envelope, structured logging, Vitest + Playwright, one-click Vercel deploy

![Dashboard preview](./.github/assets/dashboard.png)

<details>
<summary><b>More screenshots — 5 pages</b></summary>

### Kanban board (`/dashboard/kanban`)

![Kanban board](./.github/assets/kanban.png)

### Data table (`/dashboard/data-table`)

![Data table](./.github/assets/data-table.png)

### Calendar (`/dashboard/calendar`)

![Calendar](./.github/assets/calendar.png)

### Public landing (`/`)

![Landing page](./.github/assets/landing.png)

### Sign-in (`/login` — demo mode active)

![Login page](./.github/assets/login.png)

</details>

> ### Powered by [UIPKGE](https://uipkge.dev)
>
> Every UI element, block and chart in this repo comes from the **`@uipkge-react`** registry — a shadcn/ui-compatible React distribution that covers the whole shape of a SaaS app:
>
> - **Auth UI** — sign-in, sign-up, magic link, forgot password, MFA code entry, invite acceptance, onboarding stepper
> - **Marketing UI** — header, hero, logos, features, bento grid, testimonials, pricing, FAQ, CTA, contact, footer
> - **Dashboard UI** — collapsible sidebar, breadcrumbs, command palette, notifications popover, theme customizer, locale switcher, kanban, data table, calendar
> - **Charts** — area, bar, line, funnel, gauge, treemap, calendar heatmap, sparkline (ECharts via `echarts-for-react`, themed for light + dark)
> - **Forms + tables** — React Hook Form + zod fields, TanStack Table data grids
> - **Rich text** — Tiptap editor with links, placeholders, task lists, text-align, underline
> - **Elements** — button, dialog, sheet, command, popover, tooltip, context menu, date/range calendar, pin input, file upload, slider, …
>
> Same design tokens, same theming, same Tailwind CSS 4 setup. One CLI command:
>
> ```bash
> npx shadcn@latest add @uipkge-react/<name> -y
> ```
>
> The source is copied into your project — fully owned, fully editable, no runtime dependency. [Browse the React catalog →](https://uipkge.dev/react/components) · [Jump to the UIPKGE section ↓](#uipkge-ui-registry)

---

## Quick start

```bash
git clone https://github.com/uday-a/next-boilerplate my-app
cd my-app
npm install
echo "AUTH_SECRET=$(openssl rand -base64 32)" > .env
npm run dev
# → http://localhost:3000
# → http://localhost:3000/login  (Continue as demo user)
```

Demo mode is **on by default in local development only** (`next dev`), so `/login` shows **Continue as demo user** with no further config. Every deployment — production *and* Vercel preview — is **opt-in**: set `DEMO_MODE=true` / `NEXT_PUBLIC_DEMO_MODE=true` to enable it (e.g. for a public live demo), or `false` to force it off. Demo sessions are **admin**, so only enable it where that's intended.

### Routes

| Area | Path | Notes |
|------|------|-------|
| Landing | `/` | Marketing blocks; header/hero/CTA adapt when signed in |
| Pricing | `/pricing` | Plan cards → Polar checkout |
| Terms / Privacy | `/terms`, `/privacy` | Legal page shells |
| Sign in | `/login` | GitHub OAuth, magic-link form, demo sign-in bar |
| Sign up | `/sign-up` | GitHub OAuth (other providers in the block are disabled) |
| Forgot password | `/forgot-password` | Sends a magic link (no password auth) |
| MFA | `/mfa` | 6-digit code UI — **mock only**, not enforced |
| Invite | `/invite/[token]` | Verify + accept a team invite |
| Onboarding | `/onboarding` | 3-step stepper (profile → workspace → invite) — UI only |
| Dashboard | `/dashboard` | KPIs, charts, Leaflet map, date-range filter |
| Messages | `/dashboard/messages` | Inbox / thread UI |
| Kanban | `/dashboard/kanban` | Registry kanban board |
| Customers | `/dashboard/data-table` | TanStack Table (sort, filter, paginate) |
| Calendar | `/dashboard/calendar` | Month grid, context menus, event dialog |
| Activity | `/dashboard/activity` | Activity heatmap + month grid |
| Locations | `/dashboard/locations` | Office directory with filters and local times |
| UI kit | `/dashboard/ui-kit` | Every installed primitive on one page |
| Forms | `/dashboard/forms`, `/dashboard/form-example` | Form controls + zod / React Hook Form reference |
| Projects | `/projects`, `/projects/[slug]` | CRUD backed by `/api/projects` |
| Feedback / Support | `/feedback`, `/support` | Feedback form (emails ops) + help center |
| Settings | `/settings/*` | general, account, security, notifications, billing, team, api-keys, activity, integrations, limits |
| Admin | `/admin/users`, `/admin/roles` | Admin-only user list, RBAC permission matrix |

All dashboard, settings, projects, feedback, support, onboarding and admin routes are protected by `proxy.ts`, which redirects to `/login?next=…`.

---

## Features

### Developer experience

- **Next.js 16** App Router + **React 19** + **TypeScript**
- **Turbopack** dev server (`next dev --turbopack`)
- **zod-validated env** at boot (`lib/env.ts`) — invalid or half-configured integrations (e.g. Polar token without webhook secret, Axiom token without dataset) fail loud
- **`components.json`** pre-wired for the `@uipkge-react` registry
- **`npm run bootstrap:registry`** — refresh installed registry items from a sibling `uipkge-ui` checkout
- **ESLint 9** (`eslint-config-next`), **Vitest** unit tests, **Playwright** end-to-end tests

### Frontend

- **Tailwind CSS 4** with UIPKGE OKLCH design tokens (`app/globals.css`)
- **Dark mode** — light / dark / system via `next-themes`
- **Theme customizer** — 14 accent color themes (`lib/color-themes.ts`)
- **Command palette** — ⌘K / Ctrl K (`cmdk`)
- **Notifications popover**, breadcrumbs, collapsible sidebar, demo-data banners
- **Radix UI** primitives, **lucide-react** icons, **sonner** toasts
- **TanStack Table**, **React Hook Form** + zod, **ECharts**, **Tiptap**, **Leaflet**

### Backend (Route Handlers)

- **Typed API envelope** — routes return `{ ok: true, data }` or `{ ok: false, error: { code, message, details? } }` (`lib/api/response.ts`)
- **Structured error codes** — `UNAUTHORIZED`, `SESSION_INVALID`, `FORBIDDEN`, `NOT_FOUND`, `VALIDATION_FAILED`, `RATE_LIMITED`, `INTERNAL`
- **`requireAuth()` / `requireRole()`** guards (`server/utils/guards.ts`)
- **Rate limiting** — in-memory sliding window per IP on demo sign-in, magic link, team invites and API-key creation (`server/utils/rate-limit.ts`)
- **Audit log** — append-only `audit_logs` table written by `recordAudit()` for API-key and invite events; surfaced at `/settings/activity`
- **API keys** — create / list / revoke at `/settings/api-keys`; SHA-256 hashed, shown once, prefixed `uipkge_`, scoped. A `verifyApiKey()` helper is included but not yet wired into any route
- **Structured logger** — dot-namespaced events to stdout, optional Axiom shipping
- **Open-redirect-safe** `?next=` handling after sign-in (`lib/auth/redirect.ts`)

## Authentication

- **GitHub OAuth** — `GET /api/auth/github` + `/api/auth/github/callback` (GitHub is the only wired OAuth provider)
- **Magic link** — `POST /api/auth/magic-link` emails a single-use, hashed, expiring token; `GET` verifies it. Needs `DATABASE_URL` (Resend optional — the link is logged to stdout without it)
- **Demo sign-in** — `POST /api/auth/demo` mints a demo-user session; `/login` shows **Continue as demo user**
- **Sessions** — `iron-session` encrypted cookies (`AUTH_SECRET`)
- **Route protection** — `proxy.ts` gates protected prefixes
- **Team invites** — admins/editors invite by email + role; hashed token, 7-day TTL, single-use, accepted at `/invite/[token]`
- **Admin bootstrap** — `INITIAL_ADMIN_LOGINS` lists GitHub usernames that get `role='admin'` on sign-in

> The Nuxt sibling wires 44 OAuth providers; this repo currently wires GitHub only. MFA and the onboarding stepper are UI screens, not enforced flows.

## Admin & RBAC

- `user_role` Postgres enum: `user`, `admin`, `editor`
- Server-side enforcement with `requireRole('admin', …)` — e.g. `/api/admin/users` (admin only), team invites (admin or editor)
- `/admin/users` — admin user list
- `/admin/roles` — permission-matrix UI (owner / admin / editor / viewer / billing) backed by mock data, session-only

## Database

- **Drizzle ORM** + **`postgres`** driver, lazy singleton (`server/db/index.ts`)
- Works with Neon, Supabase (pooler), Railway, RDS or local Postgres
- Schema (`server/db/schema.ts`): `users`, `projects`, `subscriptions`, `magic_link_tokens`, `api_keys`, `audit_logs`, `invites`
- Migrations in `server/db/migrations` — `npm run db:generate` / `npm run db:migrate`
- Without `DATABASE_URL`, demo sessions and GitHub sign-in still work; demo sessions get sample projects, API keys and team members instead of DB rows

## Billing

Polar.sh (`@polar-sh/sdk`):

- **Checkout** — `POST /api/billing/checkout` (Pro / Team / Enterprise product IDs)
- **Customer portal** — `POST /api/billing/portal`
- **Subscription status** — `GET /api/me/subscription`, shown at `/settings/billing`
- **Webhook** — `POST /api/webhooks/polar`, signature-verified, upserts `subscription.*` events

## Email

Resend: magic-link, team-invite and feedback emails (`server/utils/mailer.ts`). Without `RESEND_API_KEY`, emails are logged to stdout. Feedback goes to `EMAIL_OPS` (falls back to `EMAIL_FROM`).

## i18n

- **next-intl** with English and Spanish (`messages/en.json`, `messages/es.json`)
- Single-URL strategy — locale stored in the `uipkge-locale` cookie, no locale-prefixed routes; switch via the locale switcher
- **Over-the-air translations (optional)** — set `I18NOW_PROJECT_ID` (+ `I18NOW_API_KEY`) and published CDN translations merge over the local files

## Observability & analytics

- **Axiom** — structured log shipping when `AXIOM_TOKEN` + `AXIOM_DATASET` are set
- **PostHog** — client analytics with page-view capture when `NEXT_PUBLIC_POSTHOG_KEY` is set
- **Sentry** — env vars are validated in `lib/env.ts`, but the Sentry SDK is **not installed or wired** yet

---

## UIPKGE UI registry

This boilerplate is wired to the [**`@uipkge-react`**](https://uipkge.dev/react/setup) registry. Items install with the standard shadcn CLI and land under `components/` — fully owned, fully editable.

```bash
npx shadcn@latest add @uipkge-react/button -y
npx shadcn@latest add @uipkge-react/kanban-board -y
```

Already configured in [`components.json`](./components.json):

```json
{
  "registries": {
    "@uipkge-react": "https://uipkge.dev/r/react/{name}.json"
  }
}
```

Browse the catalog at **[uipkge.dev/react/components](https://uipkge.dev/react/components)** · the Vue sibling uses **`@uipkge`** at [uipkge.dev/vue/components](https://uipkge.dev/vue/components).

---

## Tech stack

| Layer | Library |
|---|---|
| Framework | [Next.js 16](https://nextjs.org) (App Router, Turbopack), [React 19](https://react.dev), TypeScript |
| Auth | [iron-session](https://github.com/vvo/iron-session) + GitHub OAuth + magic links |
| ORM / DB | [Drizzle ORM](https://orm.drizzle.team) + [postgres](https://github.com/porsager/postgres) |
| Styling | [Tailwind CSS 4](https://tailwindcss.com), [next-themes](https://github.com/pacocoursey/next-themes) |
| Components | shadcn/ui-compatible [`@uipkge-react`](https://uipkge.dev) on [Radix UI](https://www.radix-ui.com) |
| Tables | [TanStack Table](https://tanstack.com/table) |
| Forms | [React Hook Form](https://react-hook-form.com) + [Zod](https://zod.dev) |
| Editor | [Tiptap](https://tiptap.dev) |
| Charts | [ECharts](https://echarts.apache.org) via echarts-for-react |
| Maps | [Leaflet](https://leafletjs.com) |
| i18n | [next-intl](https://next-intl.dev) |
| Icons | [lucide-react](https://lucide.dev) |
| Billing | [Polar.sh](https://polar.sh) |
| Email | [Resend](https://resend.com) |
| Logs / analytics | [Axiom](https://axiom.co), [PostHog](https://posthog.com) |
| Testing | [Vitest](https://vitest.dev), [Testing Library](https://testing-library.com), [Playwright](https://playwright.dev) |

---

## Requirements

- **Node 22+** (`engines` in `package.json`, `.nvmrc`)
- **npm** (lockfile is `package-lock.json`)
- *Optional:* a Postgres URL — needed for persistence, magic links and team invites

---

## Getting started

### 1. Clone + install

```bash
git clone https://github.com/uday-a/next-boilerplate my-app
cd my-app
npm install
```

### 2. Environment

```bash
cp .env.example .env
# then set AUTH_SECRET in .env to the output of:
openssl rand -base64 32
```

Only `AUTH_SECRET` is required (32+ chars). Everything else is optional — see the matrix below.

### 3. Database (optional)

```bash
# Set DATABASE_URL in .env first, then:
npm run db:migrate
```

### 4. Run

```bash
npm run dev        # http://localhost:3000
npm run build      # production build
npm run start      # serve production build
```

Open **[http://localhost:3000/login](http://localhost:3000/login)** → **Continue as demo user**.

---

## Project structure

```
.
├── app/
│   ├── (marketing)/          # landing, pricing, legal, login, sign-up, forgot-password, mfa, invite, onboarding
│   ├── (dashboard)/          # sidebar shell: dashboard/*, projects, settings/*, admin/*, feedback, support
│   └── api/                  # Route Handlers: auth, me, projects, keys, team, activity, admin, billing, webhooks, feedback
├── components/
│   ├── blocks/               # @uipkge-react blocks (Header01, Hero01, CommandPalette, kanban-board, …)
│   └── ui/                   # primitives + charts + leaflet-map
├── i18n/request.ts           # next-intl request config (cookie locale + OTA merge)
├── messages/                 # en.json, es.json
├── lib/                      # env, api/response, auth, demo-mode, i18n, demo data, hooks
├── server/
│   ├── db/                   # Drizzle schema + migrations
│   └── utils/                # guards, audit, api-keys, rate-limit, logger, mailer, polar, tokens, i18now
├── e2e/                      # Playwright specs
├── scripts/                  # registry bootstrap, locale converter
├── proxy.ts                  # auth gate → /login?next=…
├── components.json           # shadcn CLI + @uipkge-react registry
└── .env.example
```

---

## Graceful degradation matrix

| Env var(s) | Unset | Set |
|---|---|---|
| `AUTH_SECRET` | **Boot fails** — required (32+ chars) | Sessions encrypted |
| `DEMO_MODE` / `NEXT_PUBLIC_DEMO_MODE` | Auto: on in `next dev` only; off in every deployment (production and preview) | `true` enables demo sign-in (admin session) — required for a public live demo; `false` forces it off |
| `GITHUB_CLIENT_ID` + `GITHUB_CLIENT_SECRET` | GitHub sign-in unavailable | GitHub OAuth |
| `INITIAL_ADMIN_LOGINS` | Nobody auto-promoted | Listed GitHub logins become admins |
| `DATABASE_URL` | Demo sessions use sample data; magic links, invites and persistence unavailable | Drizzle persistence |
| `RESEND_API_KEY` + `EMAIL_FROM` / `EMAIL_OPS` | Emails logged to stdout | Real delivery |
| `POLAR_ACCESS_TOKEN` + `POLAR_WEBHOOK_SECRET` (+ `POLAR_*_PRODUCT_ID`, `POLAR_SERVER`) | Billing routes return an instructive error | Checkout, portal, webhooks |
| `I18NOW_PROJECT_ID` + `I18NOW_API_KEY` | Local `messages/*.json` only | CDN translations merged over local |
| `AXIOM_TOKEN` + `AXIOM_DATASET` | Logs to stdout only | Logs shipped to Axiom |
| `NEXT_PUBLIC_POSTHOG_KEY` | No analytics | PostHog page views |
| `NEXT_PUBLIC_SENTRY_DSN` (+ `SENTRY_*`) | — | Validated only; SDK not wired |
| `NEXT_PUBLIC_SITE_URL` | `http://localhost:3000` | OAuth redirects + email links |

---

## API conventions

```ts
// app/api/projects/route.ts (simplified)
export async function GET() {
  return apiHandler(async () => {
    const session = await requireAuth()
    return { projects: await listProjects(session.user.id) }
  })
}
```

```ts
// success
{ ok: true, data: T }
// failure
{ ok: false, error: { code, message, details? } }
```

---

## Testing

```bash
npm test             # Vitest unit tests (lib/*.test.ts, component tests)
npm run test:watch   # Vitest watch mode
npm run test:e2e     # Playwright: landing, auth flow, dashboard (starts `next dev` on :3005 unless BASE_URL is set)
npm run lint         # ESLint
```

---

## Deployment

> [!WARNING]
> **`DEMO_MODE` — demo sign-in creates an ADMIN session.** Demo mode is auto-on **only in local development** (`next dev`). Every deployment — production *and* preview — has it **off** unless you set `DEMO_MODE=true` (and `NEXT_PUBLIC_DEMO_MODE=true`) explicitly. Set it only on a deployment meant to offer a public demo; otherwise leave it unset or `false`.

### Vercel

Generate a session secret, then click:

```bash
openssl rand -base64 32
```

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/uday-a/next-boilerplate&env=AUTH_SECRET,DEMO_MODE,NEXT_PUBLIC_DEMO_MODE&envDescription=AUTH_SECRET%3A%20openssl%20rand%20-base64%2032.%20Set%20DEMO_MODE%20and%20NEXT_PUBLIC_DEMO_MODE%20to%20true%20only%20for%20a%20public%20demo%20(demo%20sessions%20are%20admin).&project-name=next-boilerplate&repository-name=next-boilerplate)

| Variable | Required | Value |
|----------|----------|-------|
| `AUTH_SECRET` | **Yes** | output of `openssl rand -base64 32` |
| `DEMO_MODE` | Only for a public demo (admin sessions) | `true` — otherwise leave unset or `false` |
| `NEXT_PUBLIC_DEMO_MODE` | Only for a public demo | `true` — otherwise leave unset or `false` |
| `NEXT_PUBLIC_SITE_URL` | After first deploy | `https://your-app.vercel.app` |

If you set `DEMO_MODE=true`, open **`https://<your-app>.vercel.app/login`** and click **Continue as demo user**.

### Production checklist

- [ ] Generate a fresh `AUTH_SECRET` (never reuse dev).
- [ ] Set `NEXT_PUBLIC_SITE_URL` to your real domain.
- [ ] Leave `DEMO_MODE` / `NEXT_PUBLIC_DEMO_MODE` unset or `false` (demo sign-in is an admin session).
- [ ] Register the OAuth callback: `https://<host>/api/auth/github/callback`.
- [ ] Register the Polar webhook: `https://<host>/api/webhooks/polar`.
- [ ] Run `npm run db:migrate` against the production `DATABASE_URL`.
- [ ] Note: rate limits are in-memory per instance — swap in a shared store if you need global limits.

---

## Parity with [nuxt-boilerplate](https://github.com/uday-a/nuxt-boilerplate)

This is the React/Next.js sibling of the Nuxt 4 SaaS starter: same registry-driven UI (`@uipkge-react` vs `@uipkge`), same demo sign-in on `/login`, same API envelope, same dashboard routes and translations.

| | Nuxt | Next.js (this repo) |
|---|---|---|
| Registry CLI | `npx shadcn-vue add @uipkge/<name>` | `npx shadcn@latest add @uipkge-react/<name>` |
| Session | `nuxt-auth-utils` | `iron-session` |
| OAuth | 44 providers | GitHub |
| i18n | `@nuxtjs/i18n` | `next-intl` |
| Demo sign-in | `POST /auth/demo` | `POST /api/auth/demo` |

Not ported yet: the multi-provider OAuth catalog, the onboarding tour, Sentry wiring, and the Nuxt SEO module setup.

---

## Contributing

PRs welcome. For non-trivial changes, open an issue first.

## License

MIT — see [LICENSE](./LICENSE).

## Acknowledgments

- [Next.js](https://nextjs.org) team
- [shadcn/ui](https://ui.shadcn.com) + [UIPKGE](https://uipkge.dev) for the component system
- [nuxt-boilerplate](https://github.com/uday-a/nuxt-boilerplate) — the Vue sibling this repo mirrors
- [Drizzle](https://orm.drizzle.team) for the ORM
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.