A modern, well-structured starter kit for building fast, accessible, and scalable web applications using Next.js 15, Tailwind CSS 4, and a curated set of developer tools.
- 🚀 Features
- 📦 Tech Stack
- 📁 Folder Structure
- ⚙️ Getting Started
- 🧪 Scripts
- 🛠️ Tooling Configuration
- 🧱 Development Workflow
- 🌐 Internationalization (i18n)
- ♿ Accessibility
- 🧪 Commit Guidelines
- 📚 Resources
- 📄 License
- Next.js 15 App Router with Turbopack for fast builds and instant refreshes
- Tailwind CSS 4 with
prettier-plugin-tailwindcssfor automatic class sorting - Dark mode support via
next-themes - Radix UI primitives for accessible components
- TypeScript for type-safe development
- ESLint + Prettier with a shared config for consistent formatting
- Husky + lint-staged for automated pre-commit checks
- Release It! for automated semantic versioning and changelog updates
- Commitlint + Conventional Commits for structured commit history
- ShadCN UI fully customizable, locally owned components
- Framework: Next.js 15 (App Router, Turbopack)
- Styling: Tailwind CSS v4.1, PostCSS
- Language: TypeScript
- Linting & Formatting: ESLint (Flat Config), Prettier (shared config)
- Dev Tools: pnpm, Husky, lint-staged, Commitlint, Release It!
- UI & Icons: Radix UI, Lucide, ShadCN UI
.
├── src/
│ ├── app/ # App Router entry point and global styles
│ │ ├── [locale]/ # Locale-based routing (e.g. /en, /es)
│ │ │ ├── layout.tsx # Shared layout per locale
│ │ │ ├── page.tsx # Locale-specific homepage
│ │ │ └── ... # Locale-specific subpage
│ │ ├── globals.css # Tailwind theme tokens and base styles
│ │ ├── layout.tsx # Root layout
│ │ └── ...
│ ├── components/ # Reusable UI and theme components
│ │ ├── theme-provider.tsx # Context for theme management
│ │ ├── theme-toggle.tsx # Dark mode toggle component
│ │ ├── ...
│ │ └── ui/ # ShadCN UI components
│ │ ├── button.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── language-switcher.tsx # Locale toggle component
│ │ └── ...
│ ├── i18n/ # i18n logic and routing config
│ │ ├── navigation.ts # Navigation labels per locale
│ │ ├── request.ts # Locale-aware request helpers
│ │ └── routing.ts # Supported locales and default locale
│ ├── lib/ # Shared utilities and helpers
│ │ └── utils.ts
│ ├── locales/ # Translation message files
│ │ ├── en.json
│ │ └── es.json
│ └── middleware.ts # Next.js middleware for locale detection and redirects
├── public/ # Static assets served at root
├── .husky/ # Git hooks
├── components.json # ShadCN UI CLI config
├── commitlint.config.mjs # Conventional commit rules
├── eslint.config.mjs # Flat ESLint configuration with Prettier integration
├── prettier.config.mjs # Prettier with Tailwind plugin
├── postcss.config.mjs # PostCSS config for Tailwind CSS
├── .lintstagedrc.mjs # Format and lint staged files
├── .release-it.ts # Semantic versioning and changelog
├── tsconfig.json # TypeScript configuration
└── package.json # Project metadata and npm scripts- Node.js 22+
- pnpm 10+
npx degit https://github.com/b3t0247/nextjs-tailwind my-appcd my-apppnpm installpnpm devOpen http://localhost:3000 in your browser.
| Command | Description | Notes |
|---|---|---|
pnpm dev |
Start the dev server with Turbopack | Requires Node.js 22+ |
pnpm build |
Build the app for production | Outputs to .next/ |
pnpm start |
Start the production server | Requires prior build |
pnpm lint |
Run ESLint with auto-fix | Uses Flat Config |
pnpm lint:check |
Run ESLint without auto-fix (optional) | Uses Flat Config |
pnpm format |
Format code using Prettier | Includes Tailwind plugin |
pnpm release |
Automated versioning and changelog updates | Uses .release-it.ts config |
💡 Tip: Use
pnpm lint --fixorpnpm exec prettier --write .to auto-fix issues and format all files.
| File | Purpose |
|---|---|
eslint.config.mjs |
Flat Config for ESLint with TypeScript, Prettier, and accessibility rules |
prettier.config.mjs |
Shared Prettier configuration used by both ESLint and Prettier CLI |
.lintstagedrc.mjs |
Runs ESLint and Prettier on staged files before commits using lint-staged |
.prettierignore |
Excludes files and folders from Prettier formatting |
.release-it.ts |
Automated semantic versioning and changelog generation |
commitlint.config.mjs |
Enforces Conventional Commits and custom rules for commit messages |
.husky/ |
Contains Git hooks (e.g., pre-commit) managed by Husky |
tailwind.config.ts |
Tailwind CSS configuration for design tokens, themes, and plugins |
postcss.config.mjs |
Configures PostCSS plugins (e.g., Tailwind CSS integration) |
components.json |
ShadCN UI CLI config for scaffolding components and managing aliases |
tsconfig.json |
TypeScript compiler configuration |
- Formatting tools (Prettier, ESLint, lint-staged)
- Customization options (Tailwind tokens, ESLint/Prettier configuration, ShadCN UI edits, Husky hooks)
This project uses unified configs for consistent code quality:
- Prettier: Formatting rules are defined in
prettier.config.mjsand used by both ESLint and the Prettier CLI. - ESLint: Uses native Flat Config (
eslint.config.mjs) with TypeScript, Prettier, and accessibility plugins. - lint-staged: Automatically formats staged files before commits using ESLint and Prettier.
- No
.prettierrcneeded: All formatting rules live inprettier.config.mjsto avoid duplication.
pnpm format # Runs Prettier using shared config
pnpm lint # Runs ESLint with auto-fix enabledCustomize your workflow and design system:
-
Tailwind CSS v4 follows a CSS-first configuration model. Rather than using the conventional
tailwind.config.tsfile for design tokens, this project defines them directly inglobal.cssusing Tailwind’s@theme,@custom-variant, and@layerdirectives. OKLCH-based color tokens, radius scales, and font families are set inline within the@themeblock, while base styles are applied using@layerbase. To modify the design system, editapp/global.css. -
ShadCN UI components are copied into your project and fully owned. Customize them freely using Tailwind, CVA variants, and your design tokens. ShadCN CLI scaffolds components into
@/components/ui, and aliases like@/lib/utilsand@/hookskeep your imports clean. -
ESLint Rules Extend or override rules in
eslint.config.mjsfile or your shared config package. You can also add plugins for accessibility, import sorting, or testing. -
Prettier Add a
.prettierrcfile to customize formatting preferences like tab width, trailing commas, or quote style. This project uses inline Prettier config withprettier-plugin-tailwindcssfor class sorting. -
Commitlint Adjust
commitlint.config.mjsto enforce or relax rules around commit scopes, types, or message length. -
Release Strategy Tweak
.release-it.tsto change version bumping behavior, changelog formatting, or GitHub release settings. -
Husky Hooks Add or modify Git hooks in
./huskyto run tests, type checks, or other validations before commits or pushes.
Next.js includes strong accessibility support out of the box, helping you build inclusive web experiences by default.
-
Route Announcer: Automatically announces page changes to screen readers during client-side navigation.
-
ESLint Accessibility Rules: Includes
eslint-plugin-jsx-a11yby default to catch common accessibility issues in JSX. -
Semantic HTML Encouragement: Encourages use of
<main>,<nav>,<header>, and other semantic elements. -
Keyboard Navigation: Core components like
<Link>(next/link) and<Image>(next/image) are accessible by default.
-
Descriptive Page Titles
Use<Head>to set meaningful titles for screen readers:<Head> <title>Dashboard – MyApp</title> </Head>
-
Skip to Content Link
Add a visually hidden link to let keyboard users bypass navigation:<a href="#main-content" className="sr-only focus:not-sr-only"> Skip to content </a>
-
ARIA Roles (When Needed) Use ARIA attributes for custom components like modals, tabs, or dropdowns - but prefer semantic HTML when possible.
-
Accessibility Testing Tools Use tools like axe DevTools, Lighthouse, or screen readers like NVDA or VoiceOver to audit your app.
💡 Tip: Accessibility is not just about compliance — it improves usability for everyone.
This starter kit supports locale-based routing and translations using next-intl. Pages are served in the user's preferred language, with structured translation files and shared layout components.
- Locale detection and routing via Next.js middleware
- Translation management using
next-intlmessage files - Shared layout and Providers for consistent UX across locales
- Easy extension to support additional languages
| Locale | Path Prefix | Description |
|---|---|---|
en |
/en |
English (default) |
es |
/es |
Spanish |
Translation files are stored in:
src/locales/
├── en.json
├── es.jsonEach file contains key-value pairs used throughout the app. Example:
{
"home.title": "Welcome",
"home.description": "This is the English version of the homepage."
}- Create a new JSON file in
src/locales/(e.g.fr.json) - Add the locale to the
localesarray insrc/i18n/routing.ts - Add translations for all required keys
- Use the
useTranslations()hook fromnext-intlto access localized strings - Wrap your layout with `NextIntlClientProvider to enable translations
- Test locale routing by visiting
/en,/es, etc.
import { useTranslations } from "next-intl";
export default function HomePage() {
const t = useTranslations("home");
return (
<main>
<h1>{t("title")}</h1>
<p>{t("description")}</p>
</main>
);
}💡 Tip: You can preview locale-specific pages by navigating directly to
/en,/es, etc. Middleware handles redirection based on browser language preferences.
This project uses Conventional Commits for consistent commit messages.
This project is licensed under the MIT License. Feel free to use, fork, and contribute!
| Tool / Library | Purpose |
|---|---|
| Next.js 15 | React framework with App Router and Turbopack |
| Tailwind CSS | Utility-first CSS framework with OKLCH support |
| TypeScript | Static typing for JavaScript |
| Radix UI | Accessible, unstyled UI primitives |
| ShadCN UI | Build your own component library |
| Lucide | Beautiful, consistent icon set |
| Husky | Git hook manager for running scripts before commits |
| Lint-staged | Run linters on staged files before committing |
| Commitlint | Enforce Conventional Commit messages |
| Release It! | Automate versioning and changelog generation |
The easiest way to deploy this Next.js app is with Vercel, the creators of Next.js.
📘 Learn more: Next.js Deployment Docs