Introduction
Getting started is intentionally simple. You can create a new project with:
npx create-next-app@latest .
That's enough to create a Next.js project. But creating the project is only the first step.
For a real application, you will usually want consistent code formatting, linting, Git hooks, environment-variable conventions, and a project structure that can scale as the application grows.
This guide walks through a complete baseline setup so that you can move from a freshly generated Next.js application to a clean development environment ready for full-stack development.
Note: The exact prompts and defaults of
create-next-appcan change between Next.js releases. The commands below follow the current Next.js setup approach.
Steps to Complete Setup
1. Prerequisites
Before starting, make sure the following are installed.
Node.js
The current Next.js documentation requires Node.js 20.9 or newer.
Check your installed version:
node -v
You should see a version equal to or greater than:
v20.9.0
npm
npm is installed along with Node.js.
Verify it:
npm -v
Git
Git is strongly recommended for version control and will also be used by Husky later.
Check:
git --version
Code Editor
Visual Studio Code is a good choice for Next.js development.
Recommended extensions:
- ESLint
- Prettier - Code formatter
- Tailwind CSS IntelliSense
- Error Lens
- GitLens (optional)
2. Create the Next.js Application
Create the project in the current directory:
npx create-next-app@latest .
The Next.js CLI will ask you several questions.
For a modern full-stack application, the following setup is a good starting point:
| Option | Recommended |
|---|---|
| TypeScript | Yes |
| Linter | ESLint |
| React Compiler | Based on project requirements |
| Tailwind CSS | Yes |
src/ directory |
Yes |
| App Router | Yes |
| Import alias | Yes |
| Import alias value | @/* |
| AGENTS.md | Optional |
The current create-next-app documentation lists TypeScript, Tailwind CSS, ESLint, App Router, and Turbopack among the recommended/default setup options. The CLI also supports an --import-alias option and can initialize a project inside src/.
After the setup completes, start the development server:
npm run dev
Open:
http://localhost:3000
If the default Next.js page appears, your application has been successfully created.
3. Initialize Git
If Git has not already been initialized, run:
git init
Check the repository:
git status
Create the initial commit:
git add .
git commit -m "chore: initialize Next.js project"
From this point onward, Git will track your project changes.
4. Install and Configure Prettier
Why Prettier?
Prettier automatically formats your code according to a consistent style.
Without a formatter, different developers may write:
const user={name:"John",age:25}
while someone else writes:
const user = {
name: 'John',
age: 25,
};
Prettier removes this unnecessary discussion and keeps the codebase consistent.
Install Prettier
Install it locally:
npm install --save-dev --save-exact prettier
Using a local version means everyone working on the project uses the same formatter version.
Create .prettierrc
Create:
.prettierrc
Add:
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2,
"printWidth": 100
}
Create .prettierignore
Create:
.prettierignore
Add:
node_modules
.next
out
dist
coverage
public
*.lock
Format the project
Run:
npx prettier . --write
To check formatting without modifying files:
npx prettier . --check
5. Integrate Prettier with ESLint
Next.js projects can use ESLint for code-quality checks while Prettier handles formatting.
Install the compatibility configuration:
npm install --save-dev eslint-config-prettier
Open:
eslint.config.mjs
A current flat-config setup can look like this:
import { defineConfig, globalIgnores } from 'eslint/config';
import nextVitals from 'eslint-config-next/core-web-vitals';
import nextTs from 'eslint-config-next/typescript';
import prettier from 'eslint-config-prettier/flat';
export default defineConfig([
...nextVitals,
...nextTs,
prettier,
globalIgnores([
'.next/**',
'out/**',
'build/**',
'next-env.d.ts',
]),
]);
The important part is:
import prettier from 'eslint-config-prettier/flat';
and:
prettier,
This disables ESLint rules that conflict with Prettier.
Run ESLint:
npm run lint
Important: ESLint configuration can vary depending on the Next.js version and whether you selected ESLint or another linter during project creation. If your generated configuration differs, keep the Next.js-generated configuration and add the Prettier compatibility configuration rather than blindly replacing the entire file.
6. Add Useful npm Scripts
Open:
package.json
Add or update the scripts:
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "eslint .",
"format": "prettier . --write",
"format:check": "prettier . --check",
"typecheck": "tsc --noEmit"
}
}
You can now run:
Development server
npm run dev
Linting
npm run lint
Format code
npm run format
Check formatting
npm run format:check
Type checking
npm run typecheck
Production build
npm run build
This gives you a useful set of commands for everyday development.
7. Set Up Husky and lint-staged
Why Husky?
You can manually remember to run:
npm run lint
npm run format:check
npm run typecheck
before every commit.
But eventually, someone will forget.
Husky allows Git hooks to automatically run commands at specific points in the Git workflow.
For this setup, we will use a pre-commit hook.
Install Husky and lint-staged
npm install --save-dev husky lint-staged
Initialize Husky:
npx husky init
This creates the .husky directory and a pre-commit hook.
8. Configure the Pre-commit Hook
Open:
.husky/pre-commit
Replace its contents with:
npx lint-staged
Now configure lint-staged in package.json:
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,css,md,yml,yaml}": [
"prettier --write"
]
}
}
Now when you run:
git add .
and then:
git commit -m "feat: add authentication"
Husky runs the pre-commit hook.
The hook runs lint-staged, which runs ESLint and Prettier only against the relevant staged files.
This keeps commits cleaner without repeatedly processing the entire project.
9. Test Husky
Create or modify a TypeScript file.
Then:
git add .
Commit:
git commit -m "test: verify git hooks"
You should see lint-staged execute before the commit is created.
If a linting error cannot be fixed automatically, the commit should fail.
That is exactly what we want: broken code should not easily make its way into the repository.
10. Configure Environment Variables
Full-stack applications usually require secrets and configuration values such as:
- Database connection strings
- API keys
- Authentication secrets
- External service URLs
Create:
.env.local
Example:
DATABASE_URL="postgresql://..."
AUTH_SECRET="your-secret"
API_KEY="your-api-key"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
Server-only variables
Variables such as:
DATABASE_URL=
AUTH_SECRET=
API_KEY=
should remain server-side.
Public variables
Variables prefixed with:
NEXT_PUBLIC_
can be exposed to browser-side code.
For example:
NEXT_PUBLIC_APP_URL="http://localhost:3000"
Do not put secrets behind NEXT_PUBLIC_.
Create .env.example
You should also create:
.env.example
Add placeholders:
DATABASE_URL=
AUTH_SECRET=
API_KEY=
NEXT_PUBLIC_APP_URL=
This file can safely be committed and tells other developers which environment variables they need.
Security: Never commit real API keys, database passwords, authentication secrets, or production credentials to Git.
Troubleshooting
Problem 1: node or npm is not recognized
Check:
node -v
npm -v
If the commands fail, Node.js is either not installed or its installation directory is not available in your system PATH.
Install a supported Node.js version, restart your terminal, and try again.
Problem 2: npx create-next-app@latest . fails
First check your Node.js version:
node -v
The current Next.js requirement is Node.js 20.9 or newer.
You can also check the CLI help:
npx create-next-app@latest --help
If you are creating the project in the current directory using:
npx create-next-app@latest .
make sure the directory does not already contain conflicting project files.
Problem 3: Husky hook does not run
Check that the project is a Git repository:
git status
Then initialize Husky again:
npx husky init
Verify:
.husky/pre-commit
contains:
npx lint-staged
Problem 4: lint-staged fails during commit
Run it directly:
npx lint-staged
Then run the checks individually:
npm run lint
npm run format:check
npm run typecheck
Fix the reported problem, stage the changes again, and retry the commit.
Problem 5: ESLint and Prettier conflict
Make sure this package is installed:
npm install --save-dev eslint-config-prettier
Then make sure the Prettier compatibility configuration is included in your ESLint flat configuration.
Problem 6: Prettier formats files that it should not touch
Add generated directories to:
.prettierignore
For example:
.next
dist
coverage
Review the ignore file if generated or external files are being formatted unexpectedly.
Problem 7: Git commit is rejected
A rejected commit is often the expected behavior.
Your pre-commit hook may have detected:
- ESLint errors
- Formatting problems
- Invalid staged files
- Another configured validation failure
Run:
npx lint-staged
Fix the problem and commit again.
Avoid bypassing hooks unless you have a specific reason to do so.
Problem 8: Any other issue
If you are facing any other issue apart from the above mentioned faq, feel free to drop them in the comments.
Final Verification
Before you start building features, run the complete baseline:
npm run lint
npm run format:check
npm run typecheck
npm run build
If all four commands pass, you have a solid starting point for development.
Conclusion
With this setup, you now have:
- Next.js for the application framework
- TypeScript for type safety
- App Router for modern Next.js routing
- Tailwind CSS for styling
- ESLint for code-quality checks
- Prettier for consistent formatting
- Husky for Git hooks
- lint-staged for checking staged files
- Environment-variable conventions for configuration and secrets
- A scalable project structure for future features
You can now add the application-specific pieces you actually need, such as PostgreSQL, Prisma or Drizzle, authentication, validation, testing, and CI/CD.
The goal is not to install every possible tool on day one. The goal is to start with a clean, consistent foundation and add complexity only when the application requires it.
Cheers! Happy coding



Top comments (0)