An open API service indexing awesome lists of open source software.

https://github.com/michellepace/nextjs-base

Next.js16 template with modern tooling, automated testing, CI/CD via GitHub Actions, deploy to Vercel
https://github.com/michellepace/nextjs-base

biome cicd github-actions nextjs-template nextjs16 playwright playwright-mcp tailwind4 typescript vercel vitest

Last synced: about 2 months ago
JSON representation

Next.js16 template with modern tooling, automated testing, CI/CD via GitHub Actions, deploy to Vercel

Awesome Lists containing this project

README

          

![Next.js 16 - a modern template repo](x_docs/images/github-social-thin.jpg)

*A Next.js 16 template with modern tooling and CI/CD automation. Code quality checks (linting, formatting, type checking, testing) run via Lefthook locally and GitHub Actions on PRs. Dependency updates automated via Dependabot. Deployments handled by Vercel: Preview for PRs, Production for main. Assumes Claude Code.*



Homepage in light and dark modes with UI library guidance

Template homepage with light/dark mode setup โ€” UI component library still needed


---

## ๐ŸŽฏ Use This Template

**(1) Get This Repo.** Click "Use this template" โ†’ creates a new repository on your GitHub with no commit history โ€” a fresh start. Then clone it locally:

```bash
git clone https://github.com/YOUR-USERNAME/YOUR-REPO.git
cd YOUR-REPO
npm install # Install dependencies
npm run dev # Open http://localhost:3000 to see app running
```

**(2) Install Extensions.** In VSCode/Cursor install the extensions shown in [extensions.json](.vscode/extensions.json)

**(3) GitHub + Vercel Setup.** Follow [x_docs/project-setup.md](x_docs/project-setup.md) to set up GitHub and Vercel.

**(4) Housekeeping.** Recommended to remove [x_docs/](x_docs/) (these are my working files). Modify [CLAUDE.md](.claude/CLAUDE.md), [.mcp.json](.mcp.json), and [commands/](.claude/commands) as preferred.

**(5) Choose UI Library.** Choose one that supports Tailwind 4. [shadcn/ui](https://ui.shadcn.com/) (free) and [HeroUI v3](https://heroui.com/) (free) are both LLM friendly and use semantic tokens โ€” which makes theming easy. shadcn is ubiquitous so theme it well to stand out โ€” [tweak-cn](https://tweakcn.com/) and [theme-generator](https://shadcnstudio.com/theme-generator) are helpful. HeroUI is more visually distinct and extremely LLM friendly; it ships with agent skills too. [Tailwind Plus](https://tailwindcss.com/plus) (paid) offers components ([Catalyst](https://tailwindcss.com/plus/ui-kit)), assembled UI blocks, and full site templates, but doesn't include semantic tokens so centralised theming takes more manual work.

**(6) Decide on Icons.** Each UI library above ships with icons โ€” shadcn/ui uses [Lucide React](https://lucide.dev/guide/react/), Tailwind Plus (Catalyst) uses [Heroicons](https://heroicons.com/), HeroUI uses [Iconify](https://iconify.design/). All three let you swap to a different icon library.

**(7) Replace Template Files.** Replace `page.tsx`, `layout.tsx`, `counter.tsx`, `button.tsx`, `globals.css`, (centralised theming), `fonts.ts`, and `theme-toggle.tsx` (use an icon).

## What's Installed?

For exact list see [package.json](package.json)

| Category | Tool | What it does |
| :------- | :--- | :----------- |
| Framework | [Next.js 16.2.1](https://nextjs.org) | Core webapp foundation โ€” routing, rendering, API routes, optimisation, and builds |
| Language | [TypeScript 6](https://www.typescriptlang.org) | Static type checking with strict mode enabled |
| Styling | [Tailwind CSS v4](https://tailwindcss.com) | Utility-first CSS framework for rapid styling |
| | [next-themes](https://github.com/pacocoursey/next-themes) | Light/dark mode theming provider |
| Linting | [Biome](https://biomejs.dev) | Fast linter and formatter (replaces ESLint + Prettier) |
| | [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) | Lints markdown files for consistent formatting |
| Testing | [Vitest](https://vitest.dev) | Fast unit test runner (Vite-native, Jest-compatible) |
| | [Playwright](https://playwright.dev) | E2E browser testing (Chromium, Firefox, WebKit, Mobile) |
| | [Testing Library](https://testing-library.com) | React component testing utilities |
| Git Hooks | [Lefthook](https://lefthook.dev) | Runs checks on commit (lint, typecheck, unit tests) and push (build, E2E tests) |
| Optimisation | [React Compiler](https://react.dev/learn/react-compiler) | Automatic memoisation and performance optimisations |
| Analytics | [Vercel Speed Insights](https://vercel.com/docs/speed-insights) | Real user performance metrics viewable on Vercel |
| | [Vercel Web Analytics](https://vercel.com/docs/analytics) | Privacy-friendly visitor analytics viewable on Vercel |

## Common Additions for New Projects

When starting a new project from this template, you'll typically add:

- UI components (shadcn/ui, HeroUI v3, Tailwind Plus, etc.)
- State management (Zustand, Jotai, or React Context)
- Data fetching (React Query, SWR, or native fetch with Server Components)
- Forms (React Hook Form, Zod for validation)
- Authentication (NextAuth.js, Clerk, or Supabase Auth)
- Database/ORM (Neon or Supabase with Prisma or Drizzle. Or try Convex!)

![Explained banner](x_docs/images/template-explained.png)

## Next.js Installation Explained

This template was initialised with the following options and then updated:

```bash
# Next.js installer
$ npx create-next-app@latest

Would you like to use TypeScript? โœ”๏ธ Yes
Which linter would you like to use? โœ”๏ธ Biome
Would you like to use React Compiler? โœ”๏ธ Yes
Would you like to use Tailwind CSS? โœ”๏ธ Yes
Would you like your code inside a src/ directory? โŒ No
Would you like to use App Router? (recommended) โœ”๏ธ Yes
Would you like to customise the import alias (@/* by default)? โŒ No

# Update all dependencies to latest versions
npm outdated # Check outdated packages (2025-11-20)
npx npm-check-updates -u # Rewrite package.json with latest
npm install # Install updated versions
```

## Config Files Explained

| File | What | Generally In This Project Template |
| :----- | :----- | :------------------ |
| โ–ข [.gitattributes](.gitattributes) | Git line ending and file type handling | Normalises line endings across platforms for consistent Git diffs |
| โ–ข [.gitignore](.gitignore) | Files and directories Git should ignore | Prevents build outputs and dependencies from being committed |
| โ–ข [.markdownlint.yaml](.markdownlint.yaml) | Markdownlint configuration | Disables strict linting rules for practical writing |
| โ–ข [.vscode/extensions.json](.vscode/extensions.json) | VS Code extension recommendations | Useful extensions to use in this Next.js project |
| โ–ข [.vscode/settings.json](.vscode/settings.json) | VS Code editor and formatting settings | Enables auto-formatting and configures Biome and Tailwind extensions |
| ๐ŸŒบ [.claude/commands/](.claude/commands) | Claude Code repeatable prompts | Write commits, evaluate CodeRabbit comments, post-merge cleanup |
| ๐ŸŒบ [.claude/rules/](.claude/rules) | Claude Code context-aware rules | Auto-injected when editing matching file paths |
| ๐ŸŒบ [.claude/settings.json](.claude/settings.json) | Claude Code permissions | Allow/Deny permissions for files, commands, websearch etc |
| ๐ŸŒบ [.mcp.json](.mcp.json) | Claude Code MCP config | Playwright MCP for browser testing, Ref MCP for docs search |
| ๐ŸŒบ [.claude/CLAUDE.md](.claude/CLAUDE.md) | Claude Code project context | Documents tech stack for Claude Code (customise!) |
| ๐Ÿ…ฝ [next.config.ts](next.config.ts) | Next.js framework configuration | Enables React Compiler and customises Next.js build settings |
| ๐Ÿ…ฝ [package.json](package.json) | Project dependencies and npm scripts | Defines project dependencies, scripts, and npm package metadata |
| ๐Ÿ…ฝ [postcss.config.mjs](postcss.config.mjs) | PostCSS plugins config for CSS processing | Enables Tailwind CSS v4 processing via PostCSS plugin |
| ๐Ÿงช [biome.json](biome.json) | Biome linter and formatter | Sets linting rules, formatting style, and import organisation |
| ๐Ÿงช [lefthook.yml](lefthook.yml) | Git hooks manager | Automates code quality checks on commit and build + E2E tests on push |
| ๐Ÿงช [tsconfig.json](tsconfig.json) | TypeScript compiler settings | Configures TypeScript compiler options and module resolution behaviour |
| ๐Ÿงช [playwright.config.ts](playwright.config.ts) | Playwright E2E test runner configuration | Sets test browsers (desktop + mobile), parallel execution, and base URLs |
| ๐Ÿงช [.playwright/](.playwright/) | Playwright test outputs (custom organisation) | Contains test artifacts in `test-results/` and HTML `playwright-report/` (all Playwright outputs nested under `/.playwright/` for clean structure) |
| ๐Ÿงช [vitest.config.ts](vitest.config.ts) | Vitest test runner config | Sets up React component testing environment and references [vitest.setup.ts](vitest.setup.ts) |
| ๐Ÿงช [vitest.setup.ts](vitest.setup.ts) | Global test setup | Adds helpful test assertions like `expect(element).toBeVisible()` |
| ๐Ÿš€ [.github/dependabot.yml](.github/dependabot.yml) | Dependabot config | Automated dependency update PRs weekly (npm + GitHub Actions) |
| ๐Ÿš€ [.github/workflows/check-lint-type.yml](.github/workflows/check-lint-type.yml) | GitHub Actions CI workflow | Runs Biome linting/formatting checks and TypeScript type checking on PRs |
| ๐Ÿš€ [.github/workflows/test-e2e.yml](.github/workflows/test-e2e.yml) | GitHub Actions CI workflow | Runs Playwright E2E tests on PRs (builds production, tests browsers, uploads reports) |
| ๐Ÿš€ [.github/workflows/test-e2e-vercel.yml](.github/workflows/test-e2e-vercel.yml) | GitHub Actions CI workflow | Runs Playwright E2E tests against Vercel Preview deployments (triggered by Vercel) |
| ๐Ÿš€ [.github/workflows/test-unit.yml](.github/workflows/test-unit.yml) | GitHub Actions CI workflow | Runs Vitest unit tests on PRs (uses jsdom environment, React Testing Library) |

---

## CI/CD Workflow Explained

This diagram shows how CI automation integrates into a typical development workflow:

```text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๐Ÿ’ป LAPTOP: Create a new branch (tests on local dev machine)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

git checkout -b feature/add-dark-mode
โ”‚
โ”œโ”€ Commit 1: Add light/dark mode โšก pre-commit hook runs (3s)
โ”‚ โ”œโ”€ ๐ŸŽจ Biome lint and format โœ… Auto-fixed & staged
โ”‚ โ”œโ”€ ๐Ÿ” TypeScript type check โœ… Pass
โ”‚ โ””โ”€ ๐Ÿงช Vitest unit tests โœ… Pass
โ”‚ (then committed on all pass)
โ”‚
โ”œโ”€ Commit 2: (some more work here) โšก pre-commit hook runs again
โ”‚
โ””โ”€ Commit 3: (some more work here) โšก pre-commit hook runs again

git push origin feature/add-dark-mode โšก pre-PUSH hook runs (~20s)
โ”œโ”€ ๐Ÿ—๏ธ Next.js production build โœ… Pass
โ””โ”€ ๐ŸŽญ Playwright E2E tests โœ… Pass (then pushed to GH)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โ˜๏ธ GITHUB: Workflows kickoff on GitHub machines when PR is created
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Create Pull Request โ†’ GitHub Actions triggered automatically
โ”‚
โ”œโ”€ ๐Ÿค– Workflow 1: Lint & Type (biome, tsc)
โ”‚ โ”œโ”€ Checkout code
โ”‚ โ”œโ”€ Setup Node.js LTS
โ”‚ โ”œโ”€ Install dependencies (npm ci)
โ”‚ โ”œโ”€ Run Biome checks โœ… Pass
โ”‚ โ””โ”€ Run TypeScript checks โœ… Pass
โ”‚
โ”œโ”€ ๐Ÿค– Workflow 2: Unit Tests (vitest)
โ”‚ โ”œโ”€ Checkout code
โ”‚ โ”œโ”€ Setup Node.js LTS
โ”‚ โ”œโ”€ Install dependencies (npm ci)
โ”‚ โ””โ”€ Run Vitest tests โœ… Pass
โ”‚
โ””โ”€ ๐Ÿค– Workflow 3: E2E Tests (playwright)
โ”œโ”€ Checkout code
โ”œโ”€ Setup Node.js LTS
โ”œโ”€ Install dependencies (npm ci)
โ”œโ”€ Install Playwright browsers
โ”œโ”€ Build Next.js production
โ””โ”€ Run Playwright tests โœ… Pass

โ”€โ”€ Meanwhile, Vercel deploys Preview โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

๐Ÿš€ Vercel: Preview deployment ready
โ”œโ”€ โœ… Vercel deployment status check (required to merge)
โ””โ”€ Sends repository_dispatch event to GitHub

โ””โ”€ ๐Ÿค– Workflow 4: E2E Tests (Vercel Preview)
โ”œโ”€ Triggered by Vercel (not PR event)
โ”œโ”€ Runs Playwright against live Preview URL
โ”œโ”€ Tests real Vercel deployment โœ… Pass
โ””โ”€ Reports status back to PR commit

GITHUB PR Status: โœ… All checks passed

๐Ÿฐ CodeRabbit AI Review Complete
โ””โ”€ 3 nitpick comments posted:
โ”œโ”€ "Consider using const instead of let" (Button.tsx:12)
โ”œโ”€ "Add JSDoc comment" (ThemeContext.tsx:8)
โ””โ”€ "Extract magic string to constant" (utils.ts:45)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๐Ÿ’ป Back to Laptop (Addressing 1 out of 3 nitpick comments on open PR)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”œโ”€ Commit 4: Use const instead of let โšก pre-commit hook runs

git push origin feature/add-dark-mode โšก pre-push hook runs (~20s)
โ”œโ”€ ๐Ÿ—๏ธ Next.js production build โœ… Pass
โ””โ”€ ๐ŸŽญ Playwright E2E tests โœ… Pass (then pushed to GH)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ โ˜๏ธ GITHUB (Workflows kick off again on any PR changes)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

New commits pushed โ†’ GitHub Actions re-run automatically
โ”‚
โ”œโ”€ ๐Ÿค– Lint & Type โœ… Pass
โ”œโ”€ ๐Ÿค– Unit Tests โœ… Pass
โ””โ”€ ๐Ÿค– E2E Tests โœ… Pass

PR Status: โœ… All checks passed (1 new commit)
๐Ÿฐ CodeRabbit: "Looks good! 1 issue resolved."

Okay I'm ready! [Merge Pull Request] โ† Click! ๐ŸŽ‰

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Ruleset Verified: "Protect main branch" โ”‚
โ”‚ โœ… All 5 required status checks passed โ”‚
โ”‚ โœ… Branch is up to date with main โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

main branch updated (merge commit preserves 4 commits)
โ””โ”€ ๐Ÿš€ Vercel deployment triggered โ†’ Production
```

Key CI Takeaways

- Local Hooks โ€” Catch issues before commit or reaching GitHub
- GitHub Actions โ€” Validate every PR with fresh environment (reproducible CI)
- GitHub Ruleset โ€” Prevents merging broken code (all checks must pass)
- Fast Feedback โ€” Pre-commit catches 90% of issues locally in ~3s vs ~2min CI wait
- Quality Gates โ€” Code is validated 2ร— (local + CI) before reaching production

![Quick rough notes](x_docs/images/rough-notes.png)

## Quick Notes

(1) Use Ngrok to Test App From Phone

```markdown
1. Sign up and follow https://dashboard.ngrok.com/get-started/setup/linux
2. Then: (Terminal 1: `npm run dev`) + (Terminal 2: `ngrok http 3000`)
3. Ngrok gives a URL to connect from phone (shareable)
```

(2) How Vitest Pieces Work Together

```markdown
1. When you run npm test, Vitest loads vitest.config.ts
2. The config tells Vitest to use jsdom and load `vitest.setup.ts`
3. Your test files can use global test functions and extended matchers
4. The @/* import alias works in tests thanks to `vite-tsconfig-paths`
5. React components are compiled with React Compiler (matching prod)
```

(3) GitHub - A branch ruleset to be set up to protect main. Includes checks for GitHub workflow jobs to pass before merging PR to main. See [x_docs/project-setup.md](x_docs/project-setup.md).

(4) Vercel For Deploys - When you raise a PR it automatically deploys to Vercel Preview and Playwright e2e tests run on that too in addition to GitHub servers. When you merge the PR into main, you are deploying to Vercel prod. See [x_docs/project-setup.md](x_docs/project-setup.md).