Dev Encyclopedia
ArticlesToolsContactAbout

Get notified when new content drops

No spam. Just new articles, tools, and updates straight to your inbox.

Dev Encyclopedia

A reference for builders

Content

  • Articles
  • Tools
  • About
  • Contact

Connect

  • support@devencyclopedia.com
  • RSS Feed

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

ยฉ 2026 Dev Encyclopedia

Back to top โ†‘
  1. Home
  2. /Blog
  3. /Husky + Prettier + lint-staged Setup for Next.js
nextjs8 min read

Husky + Prettier + lint-staged Setup for Next.js

Set up Husky v9, Prettier, and lint-staged in your Next.js project. Step-by-step guide covering pre-commit hooks with the correct 2026 config.

Zeeshan Tofiq
Zeeshan Tofiq
May 30, 2026
On this page

On this page

  • What These Tools Do
  • Install the Tools
  • Configure Prettier
  • Initialize Husky v9
  • Configure the Pre-Commit Hook
  • Configure lint-staged
  • Test the Setup
  • Common Issues and Fixes
  • Frequently Asked Questions

Most code quality issues are caught too late: in code review, or worse, in production. Husky, Prettier, and lint-staged give you an automatic check on every single commit, right on your machine, before the code ever leaves your editor.

This guide walks through the full setup for a Next.js project using the current versions of all three tools. If you've tried this before with a guide from 2022 and it didn't work, it's probably because Husky changed its configuration format in v9.

  1. 1

    What These Tools Do

    Three tools, each with a distinct job. Together they form an automatic quality gate that runs on every commit:

    • Prettier formats your code automatically. You set the rules once (line length, single vs double quotes, trailing commas) and it handles the rest.
    • lint-staged runs linters only on the files you've staged for a commit, not your entire codebase. This keeps the pre-commit check fast even on large projects.
    • Husky connects everything to Git. It installs scripts that run automatically at key moments: in this setup, immediately before a commit is finalized.
  2. 2

    Install the Tools

    From your Next.js project root, install the three dev dependencies. Next.js already ships with ESLint configured, so you don't need to install that separately.

    bash
    npm install --save-dev prettier husky lint-staged
  3. 3

    Configure Prettier

    Create a .prettierrc file in your project root. These are sensible defaults for a Next.js TypeScript project (adjust them to your team's preference):

    json
    {
      "semi": true,
      "singleQuote": true,
      "trailingComma": "es5",
      "printWidth": 100,
      "tabWidth": 2
    }

    ๐Ÿ’ก Tip

    Also create a .prettierignore file with node_modules, .next, out, and public. This stops Prettier from touching generated files and the build output.

  4. 4

    Initialize Husky v9

    This is where most guides go wrong. Husky v9 dropped the old .huskyrc file format. Run one command to initialize it:

    bash
    npx husky init

    โ„น Info

    This creates a .husky/ directory and adds "prepare": "husky" to package.json. Any developer who runs npm install will automatically have Husky configured, no manual setup needed.

  5. 5

    Configure the Pre-Commit Hook

    Open .husky/pre-commit (it was just created by husky init). Replace its contents with a single line that triggers lint-staged:

    sh
    npx lint-staged

    โš  Warning

    Don't add prettier --write . or eslint . directly here: that runs on your entire codebase every commit. lint-staged is what scopes the run to only your staged files.

  6. 6

    Configure lint-staged

    Add a lint-staged key to your package.json. This tells it which tools to run on which file types when they're staged:

    json
    {
      "lint-staged": {
        "*.{js,jsx,ts,tsx}": [
          "eslint --fix",
          "prettier --write"
        ],
        "*.{json,css,md}": [
          "prettier --write"
        ]
      }
    }

    ๐Ÿ’ก Tip

    The --fix and --write flags tell both tools to auto-fix what they can before committing. Only issues ESLint can't auto-fix will block the commit.

  7. 7

    Test the Setup

    Stage a file with a formatting issue and try to commit. lint-staged will run both tools automatically:

    bash
    git add .
    git commit -m "test commit"

    Here's what each outcome looks like in your terminal:

    bash โ€” Success: Prettier auto-fixed, commit goes through
    โœ” Preparing lint-staged...
    โœ” Running tasks for staged files...
    โœ” Applying modifications from tasks...
    โœ” Cleaning up temporary files...
    [main abc1234] test commit
     1 file changed, 5 insertions(+)
    bash โ€” Failure: ESLint error blocks the commit
    โœ” Preparing lint-staged...
    โš  Running tasks for staged files...
      โœ– eslint --fix:
        src/app/page.tsx
          5:7  error  'myVar' is assigned a value but never used  no-unused-vars
    โœ— lint-staged failed due to a task error.

    ๐Ÿ’ก Tip

    Test both scenarios intentionally. The fastest way to understand what the setup catches is to deliberately trigger each case.

  8. 8

    Common Issues and Fixes

    These are the four most common problems developers hit after setting this up:

    โš  Hooks not running after cloning

    Someone ran npm install --ignore-scripts, which skips the prepare lifecycle script. Fix: run npm run prepare once manually.

    โš  husky: command not found

    An old .huskyrc or husky.config.js from a previous attempt is still present. Delete it and re-run npx husky init.

    โš  lint-staged runs on all files, not just staged ones

    The .husky/pre-commit file contains prettier --write . instead of npx lint-staged. Open .husky/pre-commit and replace it with just npx lint-staged.

    โ„น TypeScript errors not being caught

    This is expected: lint-staged runs tools on individual files in isolation. TypeScript's type checker needs the full project context to work. Add tsc --noEmit to a pre-push hook instead of the pre-commit hook.

    Create the pre-push hook for TypeScript checking:

    sh โ€” .husky/pre-push
    npx tsc --noEmit

    ๐Ÿ’ก Tip

    Set HUSKY=0 in your CI environment to skip all Husky hooks during automated builds: HUSKY=0 npm ci. Your CI pipeline should run lint and typecheck as separate, explicit steps.

Frequently Asked Questions

What changed between Husky v8 and v9?
Husky v8Husky v9
Initializenpx husky installnpx husky init
Config file.huskyrc / husky.config.jsNo config file: hooks are plain shell scripts
Auto-install"prepare": "husky install""prepare": "husky" (added automatically)
Hook formatJSON / JS configPlain shell script in .husky/
How do I skip the pre-commit hook for an emergency commit?

Use the --no-verify flag:

bash
git commit --no-verify -m "emergency fix"

โš  Warning

Only use this for genuine emergencies. --no-verify skips ALL hooks (Prettier, ESLint, and TypeScript checks). Commit a follow-up clean-up immediately after.

Why use lint-staged instead of running ESLint on the whole project?

Running ESLint on a large codebase before every commit gets slow: 10, 20, 30 seconds per commit. lint-staged scopes the run to only the files you've staged, keeping pre-commit checks under a second on most projects.

Should I use Prettier, ESLint, or both?
ESLintPrettier
PurposeCode quality (unused vars, type errors, logic bugs)Formatting (indentation, quotes, line breaks)
Auto-fixPartial (some rules only)Always (formatting is deterministic)
OverlapNoneNone

Run ESLint first, then Prettier. Prettier's formatting pass is the final state committed.

Will Husky hooks run in CI?

By default, yes, but you usually don't want them to. In CI, run lint and type-check directly as explicit steps.

bash
HUSKY=0 npm ci
Does this setup work with Yarn or pnpm?

Yes. Replace npm install --save-dev with yarn add --dev or pnpm add -D. The husky init command and lint-staged config are identical: only the package manager command changes.

Husky v9, Prettier, and lint-staged take about five minutes to set up and save hours of back-and-forth over formatting in code review.

Keep the pre-commit hook fast: format and lint only staged files. Move tsc --noEmit to a pre-push hook where a slower check is acceptable.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

Full stack developer with over 6 years of experience building production applications. Writes practical guides on JavaScript, TypeScript, React, Node.js, and cloud infrastructure. Focused on helping developers solve real problems with clean, maintainable code.

Enjoyed this article?

Get practical dev guides, tool updates, and new articles delivered straight to your inbox. No spam, unsubscribe anytime.

Related Articles

nextjs

How to Use Environment Variables in Next.js (Without Leaking Them to the Browser)

Learn how to use .env files in Next.js correctly. Understand NEXT_PUBLIC_, avoid common mistakes, and set variables in Vercel and Cloudflare.

May 30, 2026ยท12 min read
javascript

npm Scripts You're Probably Not Using (But Should Be)

pre/post hooks, cross-env, npm-run-all, argument passing, and built-in variables: the npm script patterns developers Google one at a time, in one place.

Jun 1, 2026ยท8 min read

On this page

  • What These Tools Do
  • Install the Tools
  • Configure Prettier
  • Initialize Husky v9
  • Configure the Pre-Commit Hook
  • Configure lint-staged
  • Test the Setup
  • Common Issues and Fixes
  • Frequently Asked Questions
Advertisement