Skip to content
/ next-template Public template

⚡ Professional Next.js boilerplate supercharged with TypeScript, TailwindCSS, Testing (Vitest + Testing Library), Storybook, Husky, and more. Built with best practices and modern tools for rapid development without compromising code quality.

Notifications You must be signed in to change notification settings

MarcossIC/next-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡Next professional boilerplate
GitHub Actions Workflow Status GitHub commit activity (branch) GitHub Created At MarcossIC

Welcome to nextjs professional boilerplate, an open source template for nextjs. It is prepared with functionalities that will help you make quality code, and will facilitate the maintainability of the code. You can find versions with different functionalities among the branches. I hope you like it

✨ Features

You can find these things in the template:

  • Nextjs Next.js - Pre-configured, with default src and app router + Bundler analyzer
  • Tailwind css TailwindCSS - By default, CSS Framework for rapid UI development
  • CVA CVA - To easily manage component variants
  • biome Biome - To find and fix linting, formatting, and import order problems
  • Typescript Typescript - By default, configured with strict types and with ts-reset for types safety
  • vitess Vitest and Testing Library Testing Library - For unit tests and integration tests
  • Storybook Storybook - To create tests and use cases for your components
  • Pre commit Husky - Configured to raise, git hooks for the pre commit, pre push and commit message
  • Commitlint Commitlint with Pre commit Conventional commit - To maintain a clean and solid commit history
  • Github Action Github Actions - Pre-configured actions for smooth workflows
  • Zod Zod - For type validation
  • Zustand Zustand - To handle global states simply and cleanly
  • Zustand T3 Env - Manage your environment variables
  • Cypress Cypress - For End-to-End (E2E) testing
  • NYC NYC - For code coverage reports and management

🎯 Getting Started

To start using this template, follow the following steps:

  1. Fork & clone repository:
git clone https://github.com/<your_username>/<repo_name>.git
  1. Install the dependencies: In this case you can use the package manager you want. I personally recommend pnpm
pnpm install
  1. Run the development server:
pnpm dev
  1. Open http://localhost:3000 with your browser to see the result.

  2. The project uses husky and patch-package to automate git hooks and validate dependencies. This is executed, with the "postinstall" every time you do install:

npx patch-package && node setup-husky.js

If you do not want to run husky on every installation, remove this && node setup-husky.js from the postinstall in the package.json

📐 Scripts Overview

The template has the following scripts available in the package.json:

  • dev: Starts the development server with Turbopack, ensuring colored output.
  • build: Builds the application for production.
  • analyze: Analyzes the bundle sizes for Client, Server, and Edge environments.
  • start: Starts the production server.
  • lint: Checks for linting, formatting, and import sorting issues using Biome.
  • lint:fix: Automatically fixes linting issues with Biome (may include unsafe changes).
  • types:check: Verifies TypeScript types without emitting files.
  • clean: Removes all generated files from .next, out, coverage, .swc, and .nyc_output.
  • commitlint:last: Verifies if the last commit follows the commitlint rules.
  • format: Checks if the code follows the correct format using Biome.
  • format:fix: Automatically fixes formatting issues and organizes imports using Biome.
  • prepare: Runs the Husky setup script.
  • unit:run: Executes unit tests using Vitest.
  • unit:watch: Runs unit tests in watch mode.
  • unit:coverage: Runs unit tests and generates a coverage report.
  • cy:open: Opens the Cypress interface for running end-to-end tests.
  • cy:run: Runs Cypress end-to-end tests in headless mode.
  • cy:serve:ci: Starts the development server and runs Cypress tests in CI mode.
  • cy:serve:app: Starts the development server and opens Cypress in interactive mode.
  • cover:unit: Generates a coverage report for unit tests using nyc.
  • cover:e2e: Combines end-to-end test coverage with nyc and prevents overwriting previous coverage data.
  • cover:report: Generates a combined coverage report for all tests.
  • cover: Cleans previous coverage data, runs unit and e2e tests, and generates a full coverage report.
  • test:storybook: Runs acceptance tests for Storybook.
  • storybook: Starts the Storybook development server on port 6006.
  • storybook:serve: Serves the pre-built Storybook at port 6006.
  • build:storybook: Builds the Storybook for deployment.
  • postinstall: Applies patches to external dependencies and runs the prepare script.

📁 Project structure

/
├── __test__/                 # In this folder all the tests
│   ├── app/                  # The structure is a mirror of src
│   ├── components/
│   ├── lib/
│   ├── styles/
│   └── types/
├── .vscode/                  # VSCode config folder
├── .github/                  # GitHub folder
├── .husky/                   # Husky Hooks
├── .storybook/               # Storybook folder
├── public/                   # Public assets folder
├── src/
│   ├── app/                  # Next JS App (App Router)
│   ├── components/           # React components
│   ├── lib/                  # 3rd party libraries configuration
│   ├── styles/               # Styles folder
│   └── models/                # Types, Enums, Models, schemas
├── .editorconfig             # Editor config
├── .nycrc.json               # NYC configuration for code coverage
├── biome.json                # Patterns eslint should ignore
├── cypress.config.ts         # Cypress configuration
├── lint-staged.config.mjs    # Lintstaged config
├── commitlint.config.cjs     # Commit lint config and commit examples
├── coverage.mjs              # Script to generate combined code coverage
├── env.ts                    # Environment variables config by t3-env
├── next.config.ts            # Next config file
├── postcss.config.cjs        # Postcss config file
├── README.md                 # README file
├── report-bundle-size.js     # Script to analyze bundle size
├── setup-husky.js            # Script to raise husky on start githooks
├── tailwind.config.mjs       # Tailwind CSS configuration
├── vitest.config.ts          # Vitest config
├── vitest-setup.ts           # Vitest testing library setup
└── tsconfig.json             # TypeScript configuration

♠️ Package manager

The template does not force you to use a specific package manager so you can choose the one you want. This is why no lock file was uploaded.

However, if you are sure of the package manager you are going to use for the project. You can upload the lock file. And change the npx commands to the one you are using.

❗ Considerations

In case you choose to use yarn as a package manager you should add some things:

  • Add this dependency:
yarn add postinstall-postinstall --save-dev
  • Update post install: You need to find the postinstall script and add the -y flag to it
"postinstall": "npx patch-package -y && node setup-husky.js"

If you have already decided on the package manager you use, you can consider adding this line to the end of your package.json:

"packageManager": "<manager>@<version>"

Example:

You only need one, but I leave you examples for these 3 handlers:

"packageManager": "[email protected]"
"packageManager": "[email protected]"
"packageManager": "[email protected]"

:shipit: Testing

We use Vitest for unit and integration tests, taking advantage of its fast performance and modern testing capabilities. For end-to-end (e2e) testing, Cypress is utilized, offering a reliable and robust browser testing framework. Additionally, we generate coverage reports using nyc, including a combined report for both unit and e2e tests.

Running Tests

Below are some examples of how to execute tests and generate coverage reports using pnpm:

  • Unit and Integration Tests: Execute tests with Vitest using pnpm unit:run or run them in watch mode with pnpm unit:watch.
  • Unit Test Coverage: Generate a coverage report for unit tests with pnpm unit:coverage.
  • End-to-End (e2e) Tests:
    • Open the Cypress interface with pnpm cy:open.
    • Run Cypress tests in headless mode with pnpm cy:run.
    • Start the app and run e2e tests in CI mode with pnpm cy:serve:ci.
  • Combined Coverage Report:
    • Generate a full coverage report (unit + e2e) by running pnpm cover. This cleans old reports, runs all tests, and generates a combined report.
    • Use pnpm cover:report to manually generate the combined report if coverage files already exist.
  • Storybook Tests: Run acceptance tests for Storybook with pnpm test:storybook.

Viewing Coverage Reports

The combined coverage report will be generated in the coverage folder. Open the index.html file inside the folder to view a detailed breakdown of test coverage for both unit and e2e tests.

This setup ensures comprehensive test coverage and streamlined testing workflows for both unit and end-to-end scenarios.

StoryBook

Storybook is a development tool that allows you to build and document user interface (UI) components in isolation. It is a kind of sandbox where you can develop and view your components independently of the rest of the application. This makes it easier to design, test, and document reusable components, allowing development and design teams to work more efficiently and collaboratively.

Storybook is not only useful for building and visualizing components, but also offers tools for automated testing, improving code quality and reliability. You can write your acceptance tests using storybook's play function. To run the storybook tests you may need to have playwright installed with (Example with pnpm):

pnpm exec playwright install --with-deps

Ready to run the Storybook tests, you must first have Storybook executed pnpm storybook and in another terminal execute pnpm test:storybook

🎨 Styling

For styles, added Tailwind CSS, a CSS framework for quick styling. In case you need to use your own CSS, it is recommended to use CSS Modules.

CVA

The template comes by default with cva, clsx and tw-merge. These utilities serve to facilitate the creation of variants for your components, this will help you maintain a design system easily. Then CVA will simplify the process of creating variants for your design systems, without compromising CSS control.

🌌 State Management

The template comes by default with Zustand, a great state manager that is quite simple, but very powerful. This great state manager is the option I recommend but if you don't like it you can use whatever you want.

Other options

In case Zustand is not your grade, it leaves you with other good options:

  • Jotai: This global state management library developed for React, and is from the same creators of Zustand. It has an atomic approach based on the concept of atoms and offers a simple and granular API to manage its state, while still being highly optimized to reduce package size.

  • Recoil: Is a state management library developed by Meta, designed specifically for React applications. It allows you to create a data flow that flows from atoms (shared state) through selectors (pure functions) and towards your React components. Its key benefit is the ability to update components only when the state they are subscribed to changes, reducing unnecessary replays and keeping your application fast and efficient.

📝 Environment Variables

T3 Env is a library that facilitates the validation and transformation of environment variables at compile time, as well as checking their types. This tool ensures that your application uses the correct environment variables and that their values ​​match the expected types, eliminating the risk of runtime errors due to incorrect use of these variables.

The configuration is managed in the env.js file. You just need to define the variables for the client and server, and then import env into any file in your project to use them.

If you have an error with the variables you will see a message similar to this in the console specifying the error:

  ❌ Invalid environment variables: { VARIABLE: [ 'Error message' ] }

:fishsticks: Husky Git Hooks

Husky makes it easy to configure and manage these git hooks directly from your project, without having to do it manually in the file system. This will allow you to automate certain tasks, which normally can be easily forgotten.

In this case there is a script that automatically raises 3 hooks for you:

pre-commit

The pre-commit hook runs just before committing, allowing you to run a script to verify or modify the code. In this case, the hook executes the command

npx lint-staged

Lint staged

Lint staged is a tool that allows you to run linters or other code quality tasks only on files that are about to be committed. This makes the validation process more efficient, by only validating in each commit the files that were modified (Assuming that the previous files have already passed the linting process). For NextJS, you can change the lint staged configuration in the .lintstagedrc.cjs file. In this case lint staged executes these two commands:

prettier --write --file "stagedFiles..."

Then

next lint --fix --file "stagedFiles..."

commit-msg

The commit-msg hook is executed before making a commit, but after validating the pre-commit, it allows you to validate the code message to maintain a convention in your project. The hook is running:

npx commitlint --edit

Commit lint

Comitlint is a tool used to ensure that commit messages follow a predefined format, such as semantic commits. This is useful for improving the readability and structure of messages, making it easier to maintain and understand project history.

pre-push

The pre-push hook is executed just before executing the push and allows you to validate the complete code before sending it to the remote repository and even cancel the push if necessary. The hook is running:

npx tsc && npx jest --detectOpenHandles --passWithNoTests

In this case, only the tests are validated before pushing

About

⚡ Professional Next.js boilerplate supercharged with TypeScript, TailwindCSS, Testing (Vitest + Testing Library), Storybook, Husky, and more. Built with best practices and modern tools for rapid development without compromising code quality.

Topics

Resources

Stars

Watchers

Forks