---
title: "lint-staged official README"
section: "raw"
type: "source"
created: "2026-08-29"
updated: "2026-08-29"
canonical: "https://pyweb.dev/wiki/raw/articles/lint-staged-official-readme-2026"
---
# lint-staged official README

[Skip to content](https://github.com/lint-staged/lint-staged#start-of-content)

You signed in with another tab or window. [Reload](https://github.com/lint-staged/lint-staged) to refresh your session.You signed out in another tab or window. [Reload](https://github.com/lint-staged/lint-staged) to refresh your session.You switched accounts on another tab or window. [Reload](https://github.com/lint-staged/lint-staged) to refresh your session.Dismiss alert

{{ message }}

### Uh oh!

There was an error while loading. [Please reload this page](https://github.com/lint-staged/lint-staged).

[lint-staged](https://github.com/lint-staged)/ **[lint-staged](https://github.com/lint-staged/lint-staged)** Public

- Sponsor







# Sponsor lint-staged/lint-staged



















##### External links





![open_collective](https://github.githubassets.com/assets/open_collective-0a706523753d.svg)



[opencollective.com/ **lint-staged**](https://opencollective.com/lint-staged)









[Learn more about funding links in repositories](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository).




[Report abuse](https://github.com/contact/report-abuse?report=lint-staged%2Flint-staged+%28Repository+Funding+Links%29)

- [Notifications](https://github.com/login?return_to=%2Flint-staged%2Flint-staged) You must be signed in to change notification settings
- [Fork\\
472](https://github.com/login?return_to=%2Flint-staged%2Flint-staged)
- [Star\\
14.7k](https://github.com/login?return_to=%2Flint-staged%2Flint-staged)


main

[**1** Branch](https://github.com/lint-staged/lint-staged/branches) [**297** Tags](https://github.com/lint-staged/lint-staged/tags)

[Go to Branches page](https://github.com/lint-staged/lint-staged/branches)[Go to Tags page](https://github.com/lint-staged/lint-staged/tags)

Go to file

Code

Open more actions menu

## Latest commit

[![iiroj](https://avatars.githubusercontent.com/u/11628889?v=4&size=40)](https://github.com/iiroj)[iiroj](https://github.com/lint-staged/lint-staged/commits?author=iiroj)

[Merge pull request](https://github.com/lint-staged/lint-staged/commit/d0c1517b61f4805a319ae416f50b1d5bdf3e137f) [#1841](https://github.com/lint-staged/lint-staged/pull/1841) [from lint-staged/changeset-release/main](https://github.com/lint-staged/lint-staged/commit/d0c1517b61f4805a319ae416f50b1d5bdf3e137f)

Open commit detailssuccess

2 days agoAug 27, 2026

[d0c1517](https://github.com/lint-staged/lint-staged/commit/d0c1517b61f4805a319ae416f50b1d5bdf3e137f) · 2 days agoAug 27, 2026

## History

[1,529 Commits](https://github.com/lint-staged/lint-staged/commits/main/)

Open commit details

[View commit history for this file.](https://github.com/lint-staged/lint-staged/commits/main/) 1,529 Commits

## Folders and files

| Name | Name | Last commit message | Last commit date |
| --- | --- | --- | --- |
| [.changeset](https://github.com/lint-staged/lint-staged/tree/main/.changeset ".changeset") | [.changeset](https://github.com/lint-staged/lint-staged/tree/main/.changeset ".changeset") | [chore(changeset): release](https://github.com/lint-staged/lint-staged/commit/f06133573350dd650bd8fed42af06502d018b830 "chore(changeset): release") | 2 days agoAug 27, 2026 |
| [.github](https://github.com/lint-staged/lint-staged/tree/main/.github ".github") | [.github](https://github.com/lint-staged/lint-staged/tree/main/.github ".github") | [ci: update Changesets action because it failed to publish](https://github.com/lint-staged/lint-staged/commit/efe5b63cc4961c80b6363fe40bac3c145e3ddbb2 "ci: update Changesets action because it failed to publish") | 2 days agoAug 27, 2026 |
| [.husky](https://github.com/lint-staged/lint-staged/tree/main/.husky ".husky") | [.husky](https://github.com/lint-staged/lint-staged/tree/main/.husky ".husky") | [chore: drop `npx` from `commit-msg` hook](https://github.com/lint-staged/lint-staged/commit/ba4001276ac6c9c17309eec05b69b0bddf426823 "chore: drop `npx` from `commit-msg` hook") | 9 months agoNov 17, 2025 |
| [bin](https://github.com/lint-staged/lint-staged/tree/main/bin "bin") | [bin](https://github.com/lint-staged/lint-staged/tree/main/bin "bin") | [fix: enable colors globally based on option](https://github.com/lint-staged/lint-staged/commit/efb23a25075d980db9edabd2f71e769fc97d48c8 "fix: enable colors globally based on option") | last monthJul 18, 2026 |
| [lib](https://github.com/lint-staged/lint-staged/tree/main/lib "lib") | [lib](https://github.com/lint-staged/lint-staged/tree/main/lib "lib") | [fix: further fix parsing options logic](https://github.com/lint-staged/lint-staged/commit/7fd685b6de614335a432a81e383a73af4d431b3a "fix: further fix parsing options logic") | last weekAug 22, 2026 |
| [screenshots](https://github.com/lint-staged/lint-staged/tree/main/screenshots "screenshots") | [screenshots](https://github.com/lint-staged/lint-staged/tree/main/screenshots "screenshots") | [docs: Add screenshot with the animated gif (](https://github.com/lint-staged/lint-staged/commit/e976a3caef523751cbf96eb532affebbc39bb7a7 "docs: Add screenshot with the animated gif (#276)  * docs: Add screenshots  * docs: Show screenshot in the README") [#276](https://github.com/lint-staged/lint-staged/pull/276) [)](https://github.com/lint-staged/lint-staged/commit/e976a3caef523751cbf96eb532affebbc39bb7a7 "docs: Add screenshot with the animated gif (#276)  * docs: Add screenshots  * docs: Show screenshot in the README") | 9 years agoSep 12, 2017 |
| [scripts](https://github.com/lint-staged/lint-staged/tree/main/scripts "scripts") | [scripts](https://github.com/lint-staged/lint-staged/tree/main/scripts "scripts") | [style: error on unused oxlint disable rules](https://github.com/lint-staged/lint-staged/commit/9bcc1f0ef1e2505b2059eaa8b73def04375de163 "style: error on unused oxlint disable rules") | last weekAug 19, 2026 |
| [test](https://github.com/lint-staged/lint-staged/tree/main/test "test") | [test](https://github.com/lint-staged/lint-staged/tree/main/test "test") | [fix: further fix parsing options logic](https://github.com/lint-staged/lint-staged/commit/7fd685b6de614335a432a81e383a73af4d431b3a "fix: further fix parsing options logic") | last weekAug 22, 2026 |
| [.editorconfig](https://github.com/lint-staged/lint-staged/blob/main/.editorconfig ".editorconfig") | [.editorconfig](https://github.com/lint-staged/lint-staged/blob/main/.editorconfig ".editorconfig") | [chore: Use https link to editorconfig.org (](https://github.com/lint-staged/lint-staged/commit/7286f02dd2c14b2b40cfcf09e7885d1da0a21fce "chore: Use https link to editorconfig.org (#631)  saves a redirect") [#631](https://github.com/lint-staged/lint-staged/pull/631) [)](https://github.com/lint-staged/lint-staged/commit/7286f02dd2c14b2b40cfcf09e7885d1da0a21fce "chore: Use https link to editorconfig.org (#631)  saves a redirect") | 7 years agoJun 18, 2019 |
| [.gitattributes](https://github.com/lint-staged/lint-staged/blob/main/.gitattributes ".gitattributes") | [.gitattributes](https://github.com/lint-staged/lint-staged/blob/main/.gitattributes ".gitattributes") | [ci: replace Travis with GitHub Actions](https://github.com/lint-staged/lint-staged/commit/4a0d2dd6723fd5898491889c8e8f17a1293e70a0 "ci: replace Travis with GitHub Actions") | 6 years agoApr 4, 2020 |
| [.gitignore](https://github.com/lint-staged/lint-staged/blob/main/.gitignore ".gitignore") | [.gitignore](https://github.com/lint-staged/lint-staged/blob/main/.gitignore ".gitignore") | [docs: Link to AgentConf talk by](https://github.com/lint-staged/lint-staged/commit/5fba40de918d27a22d709d10328ac4dacd6c9a72 "docs: Link to AgentConf talk by @okonet (#431)  Also sneak in a couple of insignificant changes.") [@okonet](https://github.com/okonet) [(](https://github.com/lint-staged/lint-staged/commit/5fba40de918d27a22d709d10328ac4dacd6c9a72 "docs: Link to AgentConf talk by @okonet (#431)  Also sneak in a couple of insignificant changes.") [#431](https://github.com/lint-staged/lint-staged/pull/431) [)](https://github.com/lint-staged/lint-staged/commit/5fba40de918d27a22d709d10328ac4dacd6c9a72 "docs: Link to AgentConf talk by @okonet (#431)  Also sneak in a couple of insignificant changes.") | 8 years agoApr 21, 2018 |
| [.node-version](https://github.com/lint-staged/lint-staged/blob/main/.node-version ".node-version") | [.node-version](https://github.com/lint-staged/lint-staged/blob/main/.node-version ".node-version") | [ci: update Node.js versions used in CI](https://github.com/lint-staged/lint-staged/commit/52366f9f3bee04319b6d0856cac55ee8d9e9f94a "ci: update Node.js versions used in CI") | last yearMay 6, 2025 |
| [.oxfmtrc.json](https://github.com/lint-staged/lint-staged/blob/main/.oxfmtrc.json ".oxfmtrc.json") | [.oxfmtrc.json](https://github.com/lint-staged/lint-staged/blob/main/.oxfmtrc.json ".oxfmtrc.json") | [style: replace `eslint` and `prettier` with `oxlint` and `oxfmt`](https://github.com/lint-staged/lint-staged/commit/68b82995a8bf07923be7e2c2eb76e76ad51cf20d "style: replace `eslint` and `prettier` with `oxlint` and `oxfmt`") | last monthJul 17, 2026 |
| [.oxlintrc.json](https://github.com/lint-staged/lint-staged/blob/main/.oxlintrc.json ".oxlintrc.json") | [.oxlintrc.json](https://github.com/lint-staged/lint-staged/blob/main/.oxlintrc.json ".oxlintrc.json") | [style: error on unused oxlint disable rules](https://github.com/lint-staged/lint-staged/commit/9bcc1f0ef1e2505b2059eaa8b73def04375de163 "style: error on unused oxlint disable rules") | last weekAug 19, 2026 |
| [CHANGELOG.md](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md "CHANGELOG.md") | [CHANGELOG.md](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md "CHANGELOG.md") | [chore(changeset): release](https://github.com/lint-staged/lint-staged/commit/f06133573350dd650bd8fed42af06502d018b830 "chore(changeset): release") | 2 days agoAug 27, 2026 |
| [CONTRIBUTING.md](https://github.com/lint-staged/lint-staged/blob/main/CONTRIBUTING.md "CONTRIBUTING.md") | [CONTRIBUTING.md](https://github.com/lint-staged/lint-staged/blob/main/CONTRIBUTING.md "CONTRIBUTING.md") | [docs: update issue template](https://github.com/lint-staged/lint-staged/commit/85a2e7bedcc1e998d050b7360df667bb3f4cbcaf "docs: update issue template") | 3 months agoMay 30, 2026 |
| [LICENSE](https://github.com/lint-staged/lint-staged/blob/main/LICENSE "LICENSE") | [LICENSE](https://github.com/lint-staged/lint-staged/blob/main/LICENSE "LICENSE") | [Initial commit](https://github.com/lint-staged/lint-staged/commit/a3a204b0084e5b5968f5c737b4255a0248925b78 "Initial commit") | 11 years agoJan 15, 2016 |
| [MIGRATION.md](https://github.com/lint-staged/lint-staged/blob/main/MIGRATION.md "MIGRATION.md") | [MIGRATION.md](https://github.com/lint-staged/lint-staged/blob/main/MIGRATION.md "MIGRATION.md") | [fix: use git stash command to list untracked files](https://github.com/lint-staged/lint-staged/commit/b1a785190ea1128f500294116e774613ddf4ad06 "fix: use git stash command to list untracked files") | 5 months agoMar 22, 2026 |
| [README.md](https://github.com/lint-staged/lint-staged/blob/main/README.md "README.md") | [README.md](https://github.com/lint-staged/lint-staged/blob/main/README.md "README.md") | [fix: further fix parsing options logic](https://github.com/lint-staged/lint-staged/commit/7fd685b6de614335a432a81e383a73af4d431b3a "fix: further fix parsing options logic") | last weekAug 22, 2026 |
| [commitlint.config.js](https://github.com/lint-staged/lint-staged/blob/main/commitlint.config.js "commitlint.config.js") | [commitlint.config.js](https://github.com/lint-staged/lint-staged/blob/main/commitlint.config.js "commitlint.config.js") | [chore: remove old config option from commitlint](https://github.com/lint-staged/lint-staged/commit/4c1498da651b1c99b4c3e6c99a75fa114d2d75b9 "chore: remove old config option from commitlint") | last weekAug 19, 2026 |
| [lint-staged.config.js](https://github.com/lint-staged/lint-staged/blob/main/lint-staged.config.js "lint-staged.config.js") | [lint-staged.config.js](https://github.com/lint-staged/lint-staged/blob/main/lint-staged.config.js "lint-staged.config.js") | [feat: add `defineConfig` helper](https://github.com/lint-staged/lint-staged/commit/90ec28245085343f56661ebc004e7b89304762dd "feat: add `defineConfig` helper") | last weekAug 19, 2026 |
| [package-lock.json](https://github.com/lint-staged/lint-staged/blob/main/package-lock.json "package-lock.json") | [package-lock.json](https://github.com/lint-staged/lint-staged/blob/main/package-lock.json "package-lock.json") | [chore(changeset): release](https://github.com/lint-staged/lint-staged/commit/f06133573350dd650bd8fed42af06502d018b830 "chore(changeset): release") | 2 days agoAug 27, 2026 |
| [package.json](https://github.com/lint-staged/lint-staged/blob/main/package.json "package.json") | [package.json](https://github.com/lint-staged/lint-staged/blob/main/package.json "package.json") | [chore(changeset): release](https://github.com/lint-staged/lint-staged/commit/f06133573350dd650bd8fed42af06502d018b830 "chore(changeset): release") | 2 days agoAug 27, 2026 |
| [tsconfig.json](https://github.com/lint-staged/lint-staged/blob/main/tsconfig.json "tsconfig.json") | [tsconfig.json](https://github.com/lint-staged/lint-staged/blob/main/tsconfig.json "tsconfig.json") | [build: update `tsconfig.json`](https://github.com/lint-staged/lint-staged/commit/5334362f37781fc3f93ef4fba1663a16ef90d00c "build: update `tsconfig.json`") | 5 months agoMar 26, 2026 |
| [vitest.config.js](https://github.com/lint-staged/lint-staged/blob/main/vitest.config.js "vitest.config.js") | [vitest.config.js](https://github.com/lint-staged/lint-staged/blob/main/vitest.config.js "vitest.config.js") | [fix: update both default index.lock and non-standard lock when latter…](https://github.com/lint-staged/lint-staged/commit/f95c1f8df3368758c44c2052e568aac1b3d4c767 "fix: update both default index.lock and non-standard lock when latter exists") | 3 months agoMay 9, 2026 |
| View all files |

## Repository files navigation

# 🚫💩 lint-staged

[Permalink: 🚫💩 lint-staged](https://github.com/lint-staged/lint-staged#-lint-staged)

Run tasks like formatters and linters against staged git files and don't let 💩 slip into your code base!

```
npm install --save-dev lint-staged # requires further setup
```

```
$ git commit

⋯ Backing up original state…
✔ Done backing up original state (1f4c047d)!
⋯ Running tasks for staged files…
    *.{json,md} — 1 file
      ⋯ prettier --write

✔ prettier --write

✔ Done running tasks for staged files!
⋯ Staging changes from tasks…
✔ Done staging changes from tasks!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!
```

Tip

Do you only want to check staged files for errors, but not edit them automatically?

You might be interested in this simpler shell script: [`lint-staged.sh`](https://github.com/lint-staged/lint-staged.sh).

## Table of Contents

[Permalink: Table of Contents](https://github.com/lint-staged/lint-staged#table-of-contents)

- [Why](https://github.com/lint-staged/lint-staged#why)
- [Installation and setup](https://github.com/lint-staged/lint-staged#installation-and-setup)
- [Changelog](https://github.com/lint-staged/lint-staged#changelog)
- [Command line flags](https://github.com/lint-staged/lint-staged#command-line-flags)
- [Configuration](https://github.com/lint-staged/lint-staged#configuration)
- [Filtering files](https://github.com/lint-staged/lint-staged#filtering-files)
- [What commands are supported?](https://github.com/lint-staged/lint-staged#what-commands-are-supported)
- [Running multiple commands in a sequence](https://github.com/lint-staged/lint-staged#running-multiple-commands-in-a-sequence)
- [Using JS configuration files](https://github.com/lint-staged/lint-staged#using-js-configuration-files)
- [Reformatting the code](https://github.com/lint-staged/lint-staged#reformatting-the-code)
- [Examples](https://github.com/lint-staged/lint-staged#examples)
- [Frequently Asked Questions](https://github.com/lint-staged/lint-staged#frequently-asked-questions)

## Why

[Permalink: Why](https://github.com/lint-staged/lint-staged#why)

Code quality tasks like formatters and linters make more sense when run before committing your code. By doing so you can ensure no errors go into the repository and enforce code style. But running a task on a whole project can be slow, and opinionated tasks such as linting can sometimes produce irrelevant results. Ultimately you only want to check files that will be committed.

This project contains a script that will run arbitrary shell tasks with a list of staged files as an argument, filtered by a specified glob pattern.

### Related blog posts and talks

[Permalink: Related blog posts and talks](https://github.com/lint-staged/lint-staged#related-blog-posts-and-talks)

- [Introductory Medium post - Andrey Okonetchnikov, 2016](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8#.8qepn2b5l)
- [Running Jest Tests Before Each Git Commit - Ben McCormick, 2017](https://benmccormick.org/2017/02/26/running-jest-tests-before-each-git-commit/)
- [AgentConf presentation - Andrey Okonetchnikov, 2018](https://www.youtube.com/watch?v=-mhY7e-EsC4)
- [SurviveJS interview - Juho Vepsäläinen and Andrey Okonetchnikov, 2018](https://survivejs.com/blog/lint-staged-interview/)
- [Prettier your CSharp with `dotnet-format` and `lint-staged`](https://johnnyreilly.com/2020/12/22/prettier-your-csharp-with-dotnet-format-and-lint-staged)

## Installation and setup

[Permalink: Installation and setup](https://github.com/lint-staged/lint-staged#installation-and-setup)

To install _lint-staged_ in the recommended way, you need to:

1. Install _lint-staged_ itself:

   - `npm install --save-dev lint-staged`
2. Set up the `pre-commit` git hook to run _lint-staged_
   - [Husky](https://github.com/typicode/husky) is a popular choice for configuring git hooks
   - Read more about git hooks [here](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
3. Install some tools like [ESLint](https://eslint.org/) or [Prettier](https://prettier.io/)
4. Configure _lint-staged_ to run code checkers and other tasks:

   - for example: `{ "*.js": "eslint" }` to run ESLint for all staged JS files
   - See [Configuration](https://github.com/lint-staged/lint-staged#configuration) for more info

Don't forget to commit changes to `package.json` and `.husky` to share this setup with your team!

Now change a few files, `git add` or `git add --patch` some of them to your commit, and try to `git commit` them.

See [examples](https://github.com/lint-staged/lint-staged#examples) and [configuration](https://github.com/lint-staged/lint-staged#configuration) for more information.

Caution

_Lint-staged_ runs `git` operations affecting the files in your repository. By default _lint-staged_ creates a `git stash` as a backup of the original state before running any configured tasks to help prevent data loss.

## Changelog

[Permalink: Changelog](https://github.com/lint-staged/lint-staged#changelog)

See [Releases](https://github.com/lint-staged/lint-staged/releases).

### Migration

[Permalink: Migration](https://github.com/lint-staged/lint-staged#migration)

For breaking changes, see [MIGRATION.md](https://github.com/lint-staged/lint-staged/blob/main/MIGRATION.md).

## Command line flags

[Permalink: Command line flags](https://github.com/lint-staged/lint-staged#command-line-flags)

```
❯ npx lint-staged --help
Usage: lint-staged [options]

-h, --help                         display this help message
-V, --version                      display the current version number
--all                              include all files tracked in Git instead of only staged (default: false). Implies "--no-stash" and "--allow-empty".
--allow-empty                      allow empty commits when tasks revert all staged changes (default: false)
-p, --concurrent <number|boolean>  the number of tasks to run concurrently, or false for serial (default: true)
-c, --config [path]                path to configuration file, or - to read from stdin
--continue-on-error                run all tasks to completion even if one fails (default: false)
--cwd [path]                       run all tasks in specific directory, instead of the current
-d, --debug                        print additional debug information (default: false)
--diff [string]                    override the default "--staged" flag of "git diff" to get list of files. Implies "--no-stash".
--diff-filter [string]             override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
--fail-on-changes                  fail with exit code 1 when tasks modify tracked files (default: false)
--no-hide-partially-staged         hide unstaged changes from partially staged files (default: true)
--hide-unstaged                    hide all unstaged changes, instead of just partially staged (default: false)
--hide-all                         hide all unstaged changes and untracked files (default: false)
--max-arg-length [number]          maximum length of the command-line argument string (default: 0)
-q, --quiet                        disable lint-staged's own console output (default: false)
-r, --relative                     pass relative filepaths to tasks (default: false)
--no-revert                        revert to original state in case of errors (default: true)
--no-stash                         enable the backup stash (default: true)
-v, --verbose                      show task output even when tasks succeed; by default only failed output is shown (default: false)

Any lost modifications can be restored from a git stash:

  > git stash list --format="%h %s"
  <git-hash> On main: lint-staged automatic backup
  > git apply --index <git-hash>
```

#### `--all`

[Permalink: --all](https://github.com/lint-staged/lint-staged#--all)

By default _lint-staged_ only runs tasks on files that include staged changes (hence the name). Use this flag to include all files tracked in Git version control (standard exclusions apply). Using this flag implies the `--no-stash` flag, disabling the automatic backup, and the `--allow-empty` flag so that _lint-staged_ doesn't fail when there are no changes after running. This makes it easier to run `npx lint-staged --all` on a clean state, for example in CI.

#### `--allow-empty`

[Permalink: --allow-empty](https://github.com/lint-staged/lint-staged#--allow-empty)

By default, when tasks undo all staged changes, lint-staged will exit with an error and abort the commit. Use this flag to allow creating empty git commits.

#### `--concurrent [number|boolean]`

[Permalink: --concurrent [number|boolean]](https://github.com/lint-staged/lint-staged#--concurrent-numberboolean)

Controls the [concurrency of tasks](https://github.com/lint-staged/lint-staged#task-concurrency) being run by lint-staged. **NOTE**: This does NOT affect the concurrency of subtasks (they will always be run sequentially). Possible values are:

- `false`: Run all tasks serially
- `true` (default) : _Infinite_ concurrency. Runs as many tasks in parallel as possible.
- `{number}`: Run the specified number of tasks in parallel, where `1` is equivalent to `false`.

#### `--config [path]`

[Permalink: --config [path]](https://github.com/lint-staged/lint-staged#--config-path)

Manually specify a path to a config file or npm package name. Note: when used, lint-staged won't perform the config file search and will print an error if the specified file cannot be found. If '-' is provided as the filename then the config will be read from stdin, allowing piping in the config like `cat my-config.json | npx lint-staged --config -`.

#### `--cwd [path]`

[Permalink: --cwd [path]](https://github.com/lint-staged/lint-staged#--cwd-path)

Change the working directory _lint-staged_ runs tasks in. Defaults to `process.cwd()` and the value can be absolute or relative to the default value.

#### `--debug`

[Permalink: --debug](https://github.com/lint-staged/lint-staged#--debug)

Log additional information about staged files, commands being executed, location of binaries, etc.

#### `--diff`

[Permalink: --diff](https://github.com/lint-staged/lint-staged#--diff)

By default tasks are filtered against all files staged in git, generated from `git diff --staged`. This option allows you to override the `--staged` flag with arbitrary revisions. For example to get a list of changed files between two branches, use `--diff="branch1...branch2"`. You can also read more from about [git diff](https://git-scm.com/docs/git-diff) and [gitrevisions](https://git-scm.com/docs/gitrevisions). This option also implies `--no-stash`.

#### `--diff-filter [string]`

[Permalink: --diff-filter [string]](https://github.com/lint-staged/lint-staged#--diff-filter-string)

By default only files that are _added_, _copied_, _modified_, or _renamed_ are included. Use this flag to override the default `ACMR` value with something else: _added_ (`A`), _copied_ (`C`), _deleted_ (`D`), _modified_ (`M`), _renamed_ (`R`), _type changed_ (`T`), _unmerged_ (`U`), _unknown_ (`X`), or _pairing broken_ (`B`). See also the `git diff` docs for [--diff-filter](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203).

#### `--continue-on-error`

[Permalink: --continue-on-error](https://github.com/lint-staged/lint-staged#--continue-on-error)

By default _lint-staged_ will "exit early" when any of the configured tasks fails, to make sure the runtime is short. With this flag, _lint-staged_ will instead run all tasks to completion and only fail at the end, allowing all task output to be seen.

#### `--fail-on-changes`

[Permalink: --fail-on-changes](https://github.com/lint-staged/lint-staged#--fail-on-changes)

By default changes made by tasks are automatically staged and added to the commit. This flag disables the behavior and makes _lint-staged_ exit with code 1, failing the commit instead. Using this flag also implies the `--no-revert` flag which means any changes made my tasks will be left in the working tree after failing, so that they can be manually staged and the commit tried again.

#### `--max-arg-length [number]`

[Permalink: --max-arg-length [number]](https://github.com/lint-staged/lint-staged#--max-arg-length-number)

The list of staged files are appended to configured tasks as arguments, and the resulting string might be too long for the current shell, especially on Windows. _Lint-staged_ tries to avoid this by splitting the list of staged files into chunks resulting in the commands being run multiple times. This behavior affects all tasks, including functions. Use the `--max-arg-length` to override the platform-specific default value if you want to avoid this. Setting `--max-arg-length=Infinity` will disable chunking completely.

#### `--no-stash`

[Permalink: --no-stash](https://github.com/lint-staged/lint-staged#--no-stash)

By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit.

#### `--no-hide-partially-staged`

[Permalink: --no-hide-partially-staged](https://github.com/lint-staged/lint-staged#--no-hide-partially-staged)

By default, unstaged changes from partially staged files will be hidden and applied back after running tasks. This option will disable this behavior, causing those changes to also be committed.

#### `--hide-unstaged`

[Permalink: --hide-unstaged](https://github.com/lint-staged/lint-staged#--hide-unstaged)

Use this option to hide all unstaged changes in tracked files, instead of just those which are also partially staged, before running tasks. The changes will be applied back after running the tasks.

#### `--hide-all`

[Permalink: --hide-all](https://github.com/lint-staged/lint-staged#--hide-all)

Add new option `--hide-all` for hiding all unstaged changes and untracked files, before running tasks. This makes it easier to run tools like [Knip](https://knip.dev/) which check for unused code. Untracked files are included in the backup stash and restored automatically after running.

#### `--quiet`

[Permalink: --quiet](https://github.com/lint-staged/lint-staged#--quiet)

Suppress all CLI output, except from tasks.

#### `--relative`

[Permalink: --relative](https://github.com/lint-staged/lint-staged#--relative)

Pass filepaths relative to `process.cwd()` (where `lint-staged` runs) to tasks. Default is `false`.

#### `--no-revert`

[Permalink: --no-revert](https://github.com/lint-staged/lint-staged#--no-revert)

By default all task modifications will be reverted in case of an error. This option will disable the behavior, and apply task modifications to the index before aborting the commit.

#### `--verbose`

[Permalink: --verbose](https://github.com/lint-staged/lint-staged#--verbose)

Show task output even when tasks succeed. By default only failed output is shown.

## Configuration

[Permalink: Configuration](https://github.com/lint-staged/lint-staged#configuration)

_Lint-staged_ can be configured in many ways:

- `lint-staged` object in your `package.json`, or [`package.yaml`](https://github.com/pnpm/pnpm/pull/1799)
- `.lintstagedrc`file in JSON or YML format, or you can be explicit with the file extension:

  - `.lintstagedrc.json`
  - `.lintstagedrc.yaml`
  - `.lintstagedrc.yml`
- `.lintstagedrc.mjs` or `lint-staged.config.mjs` file in ESM format

  - the default export value should be a configuration: `export default { ... }`
- `.lintstagedrc.cjs` or `lint-staged.config.cjs` file in CommonJS format

  - the exports value should be a configuration: `module.exports = { ... }`
- `lint-staged.config.js` or `.lintstagedrc.js` in either ESM or CommonJS format, depending on
whether your project's _package.json_ contains the `"type": "module"` option or not.
- Pass a configuration file using the `--config` or `-c` flag

Configuration should be an object where each value is a **command** to run and its key is a glob pattern to use for this command. This package uses [picomatch](https://github.com/micromatch/picomatch) for glob patterns. JavaScript files can also export advanced configuration as a function. See [Using JS configuration files](https://github.com/lint-staged/lint-staged#using-js-configuration-files) for more info.

You can also place multiple configuration files in different directories inside a project. For a given staged file, the closest configuration file will always be used and tasks will by default run in the directory of the config (for example, the directory of a specific package in a monorepo). See ["How to use `lint-staged` in a multi-package monorepo?"](https://github.com/lint-staged/lint-staged#how-to-use-lint-staged-in-a-multi-package-monorepo) for more info and an example.

#### `package.json` example:

[Permalink: package.json example:](https://github.com/lint-staged/lint-staged#packagejson-example)

```
{
  "lint-staged": {
    "*": "your-cmd"
  }
}
```

#### `.lintstagedrc.json` example

[Permalink: .lintstagedrc.json example](https://github.com/lint-staged/lint-staged#lintstagedrcjson-example)

```
{
  "*": "your-cmd"
}
```

This config will execute `your-cmd` with the list of currently staged files passed as arguments.

So, considering you did `git add file1.ext file2.ext`, lint-staged will run the following command:

`your-cmd file1.ext file2.ext`

### TypeScript

[Permalink: TypeScript](https://github.com/lint-staged/lint-staged#typescript)

_Lint-staged_ provides TypeScript types for the configuration and main Node.js API. You can use the `defineConfig` helper in your JS configuration files:

```
import { defineConfig } from 'lint-staged/config'

export default defineConfig({
  '*': 'prettier --write',
})
```

It's also possible to use the `.ts` file extension for the configuration if your Node.js version supports it. The `--experimental-strip-types` flag was introduced in [Node.js v22.6.0](https://github.com/nodejs/node/releases/tag/v22.6.0) and unflagged in [v23.6.0](https://github.com/nodejs/node/releases/tag/v23.6.0), enabling Node.js to execute TypeScript files without additional configuration.

```
export NODE_OPTIONS="--experimental-strip-types"

npx lint-staged --config lint-staged.config.ts
```

### Task concurrency

[Permalink: Task concurrency](https://github.com/lint-staged/lint-staged#task-concurrency)

By default _lint-staged_ will run configured tasks concurrently. This means that for every glob, all the commands will be started at the same time. With the following config, both `eslint` and `prettier` will run at the same time:

```
{
  "*.ts": "eslint",
  "*.md": "prettier --list-different"
}
```

This is typically not a problem since the globs do not overlap, and the commands do not make changes to the files, but only report possible errors (aborting the git commit). If you want to run multiple commands for the same set of files, you can use the array syntax to make sure commands are run in order. In the following example, `prettier` will run for both globs, and in addition `eslint` will run for `*.ts` files _after_ it. Both sets of commands (for each glob) are still started at the same time (but do not overlap).

```
{
  "*.ts": ["prettier --list-different", "eslint"],
  "*.md": "prettier --list-different"
}
```

If you want to run tasks parallely for a specific glob, you can nest one extra layer of arrays, inside the array. In the following example, `prettier` and `eslint` will run in parallel for `*.ts` files, while the two globs also run in parallel.

```
{
  "*.ts": [["prettier --list-different", "eslint"]],
  "*.md": "prettier --list-different"
}
```

* * *

Pay extra attention when the configured globs overlap, and tasks make edits to files. For example, in this configuration `prettier` and `eslint` might try to make changes to the same `*.ts` file at the same time, causing a _race condition_:

```
{
  "*": "prettier --write",
  "*.ts": "eslint --fix"
}
```

You can solve it using the negation pattern and the array syntax:

```
{
  "!(*.ts)": "prettier --write",
  "*.ts": ["eslint --fix", "prettier --write"]
}
```

Another example in which tasks make edits to files and globs match multiple files but don't overlap:

```
{
  "*.css": ["stylelint --fix", "prettier --write"],
  "*.{js,jsx}": ["eslint --fix", "prettier --write"],
  "!(*.css|*.js|*.jsx)": ["prettier --write"]
}
```

Or, if necessary, you can limit the concurrency using `--concurrent <number>` or disable it entirely with `--concurrent false`.

## Filtering files

[Permalink: Filtering files](https://github.com/lint-staged/lint-staged#filtering-files)

Task commands work on a subset of all staged files, defined by a _glob pattern_. lint-staged uses [picomatch](https://github.com/micromatch/picomatch) for matching files with the following rules:

- If the glob pattern contains no slashes (`/`), picomatch's `matchBase` option will be enabled, so globs match a file's basename regardless of directory:

  - `"*.js"` will match all JS files, like `/test.js` and `/foo/bar/test.js`
  - `"!(*test).js"` will match all JS files, except those ending in `test.js`, so `foo.js` but not `foo.test.js`
  - `"!(*.css|*.js)"` will match all files except CSS and JS files
- If the glob pattern does contain a slash (`/`), it will match for paths as well:

  - `"./*.js"` will match all JS files in the git repo root, so `/test.js` but not `/foo/bar/test.js`
  - `"foo/**/*.js"` will match all JS files inside the `/foo` directory, so `/foo/bar/test.js` but not `/test.js`

When matching, lint-staged will do the following

- Resolve the git root automatically, no configuration needed.
- Pick the staged files which are present inside the project directory.
- Filter them using the specified glob patterns.
- Pass absolute paths to the tasks as arguments.

**NOTE:**`lint-staged` will pass _absolute_ paths to the tasks to avoid any confusion in case they're executed in a different working directory (i.e. when your `.git` directory isn't the same as your `package.json` directory).

Also see [How to use `lint-staged` in a multi-package monorepo?](https://github.com/lint-staged/lint-staged#how-to-use-lint-staged-in-a-multi-package-monorepo)

### Ignoring files

[Permalink: Ignoring files](https://github.com/lint-staged/lint-staged#ignoring-files)

The concept of `lint-staged` is to run configured linter tasks (or other tasks) on files that are staged in git. `lint-staged` will always pass a list of all staged files to the task, and ignoring any files should be configured in the task itself.

Consider a project that uses [`prettier`](https://prettier.io/) to keep code format consistent across all files. The project also stores minified 3rd-party vendor libraries in the `vendor/` directory. To keep `prettier` from throwing errors on these files, the vendor directory should be added to prettier's ignore configuration, the `.prettierignore` file. Running `npx prettier .` will ignore the entire vendor directory, throwing no errors. When `lint-staged` is added to the project and configured to run prettier, all modified and staged files in the vendor directory will be ignored by prettier, even though it receives them as input.


[... middle omitted — see footer ...]


### Using with JetBrains IDEs _(WebStorm, PyCharm, IntelliJ IDEA, RubyMine, etc.)_

[Permalink: Using with JetBrains IDEs (WebStorm, PyCharm, IntelliJ IDEA, RubyMine, etc.)](https://github.com/lint-staged/lint-staged#using-with-jetbrains-ides-webstorm-pycharm-intellij-idea-rubymine-etc)

Click to expand

_**Update**_: The latest version of JetBrains IDEs now support running hooks as you would expect.

When using the IDE's GUI to commit changes with the `precommit` hook, you might see inconsistencies in the IDE and command line. This is [known issue](https://youtrack.jetbrains.com/issue/IDEA-135454) at JetBrains so if you want this fixed, please vote for it on YouTrack.

Until the issue is resolved in the IDE, you can use the following config to work around it:

husky v1.x

```
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "post-commit": "git update-index --again"
    }
  }
}
```

husky v0.x

```
{
  "scripts": {
    "precommit": "lint-staged",
    "postcommit": "git update-index --again"
  }
}
```

_Thanks to [this comment](https://youtrack.jetbrains.com/issue/IDEA-135454#comment=27-2710654) for the fix!_

### How to use `lint-staged` in a multi-package monorepo?

[Permalink: How to use lint-staged in a multi-package monorepo?](https://github.com/lint-staged/lint-staged#how-to-use-lint-staged-in-a-multi-package-monorepo)

Click to expand

Install _lint-staged_ on the monorepo root level and add separate configuration files in each package. _Lint-staged_ will find each config file and match staged files to the closest config. The directory of each config file will be used as the working directory for those tasks, unless `--cwd` option is used. This is almost the same as running multiple processes of _lint-staged_ in parallel for each config, but multiple parallel locking Git operations are avoided.

For example, in a monorepo with `packages/frontend/.lintstagedrc.json` and `packages/backend/.lintstagedrc.json`, a staged file inside `packages/frontend/` will only match that configuration, and not the one in `packages/backend/`.

**Note**: _lint-staged_ does not merge config files, so if the closest config file to a staged file doesn't match it, the file will be ignored. For example:

```
// ./.lintstagedrc.json
{ "*.md": "prettier --write" }
```

```
// ./packages/frontend/.lintstagedrc.json
{ "*.js": "eslint --fix" }
```

When committing `./packages/frontend/README.md`, it **will not run** _prettier_, because the configuration in the `frontend/` directory is closer to the file and doesn't include it. You should treat all _lint-staged_ configuration files as isolated and separated from each other. You can always use JS files to "extend" configurations, for example:

```
import baseConfig from '../.lintstagedrc.js'

export default {
  ...baseConfig,
  '*.js': 'eslint --fix',
}
```

**Note**: If you want to run _lint-staged_ in only one package inside a monorepo, you can simply use the `--cwd` option (for example `lint-staged --cwd packages/frontend`).

**Note**: It is possible to run all tasks in the monorepo root by explicitly configuring `lint-staged --cwd="."`.

### Can I lint files outside of the current project folder?

[Permalink: Can I lint files outside of the current project folder?](https://github.com/lint-staged/lint-staged#can-i-lint-files-outside-of-the-current-project-folder)

Click to expand

tl;dr: Yes, but the pattern should start with `../`.

By default, `lint-staged` executes tasks only on the files present inside the project folder(where `lint-staged` is installed and run from).
So this question is relevant _only_ when the project folder is a child folder inside the git repo.
In certain project setups, it might be desirable to bypass this restriction. See [#425](https://github.com/lint-staged/lint-staged/issues/425), [#487](https://github.com/lint-staged/lint-staged/issues/487) for more context.

`lint-staged` provides an escape hatch for the same(`>= v7.3.0`). For patterns that start with `../`, all the staged files are allowed to match against the pattern.
Note that patterns like `*.js`, `**/*.js` will still only match the project files and not any of the files in parent or sibling directories.

Example repo: [sudo-suhas/lint-staged-django-react-demo](https://github.com/sudo-suhas/lint-staged-django-react-demo).

### Can I run `lint-staged` in CI, or when there are no staged files?

[Permalink: Can I run lint-staged in CI, or when there are no staged files?](https://github.com/lint-staged/lint-staged#can-i-run-lint-staged-in-ci-or-when-there-are-no-staged-files)

Click to expand

Lint-staged will by default run against files staged in git, and should be run during the git pre-commit hook, for example. It's also possible to override this default behaviour and run against files in a specific diff, for example
all changed files between two different branches. If you want to run _lint-staged_ in the CI, maybe you can set it up to compare the branch in a _Pull Request_/ _Merge Request_ to the target branch.

Try out the `git diff` command until you are satisfied with the result, for example:

```
git diff --diff-filter=ACMR --name-only main...my-branch
```

This will print a list of _added_, _changed_, _modified_, and _renamed_ files between `main` and `my-branch`.

You can then run lint-staged against the same files with:

```
npx lint-staged --diff="main...my-branch"
```

Note that --diff="main..my-branch" will have files that changed on `main` and are not yet caught up on `my-branch` be detected as changed files.

To see just that changes on the current branch, as compared to `main` you may wish to use:

```
npx lint-staged --diff="$(git merge-base main HEAD)"
```

### Can I use `lint-staged` with `ng lint`

[Permalink: Can I use lint-staged with ng lint](https://github.com/lint-staged/lint-staged#can-i-use-lint-staged-with-ng-lint)

Click to expand

You should not use `ng lint` through _lint-staged_, because it's designed to lint an entire project. Instead, you can add `ng lint` to your git pre-commit hook the same way as you would run lint-staged.

See issue [!951](https://github.com/lint-staged/lint-staged/issues/951) for more details and possible workarounds.

### How can I ignore files from `.eslintignore`?

[Permalink: How can I ignore files from .eslintignore?](https://github.com/lint-staged/lint-staged#how-can-i-ignore-files-from-eslintignore)

Click to expand

ESLint throws out `warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override` warnings that breaks the linting process ( if you used `--max-warnings=0` which is recommended ).

#### ESLint < 7

[Permalink: ESLint < 7](https://github.com/lint-staged/lint-staged#eslint--7)

Click to expand

Based on the discussion from [this issue](https://github.com/eslint/eslint/issues/9977), it was decided that using [the outlined script](https://github.com/eslint/eslint/issues/9977#issuecomment-406420893) is the best route to fix this.

So you can setup a `.lintstagedrc.js` config file to do this:

```
import { CLIEngine } from 'eslint'

export default {
  '*.js': (files) => {
    const cli = new CLIEngine({})
    return 'eslint --max-warnings=0 ' + files.filter((file) => !cli.isPathIgnored(file)).join(' ')
  },
}
```

#### ESLint >= 7

[Permalink: ESLint >= 7](https://github.com/lint-staged/lint-staged#eslint--7-1)

Click to expand

In versions of ESLint > 7, [isPathIgnored](https://eslint.org/docs/developer-guide/nodejs-api#-eslintispathignoredfilepath) is an async function and now returns a promise. The code below can be used to reinstate the above functionality.

Since [10.5.3](https://github.com/lint-staged/lint-staged/releases), any errors due to a bad ESLint config will come through to the console.

```
import { ESLint } from 'eslint'

const removeIgnoredFiles = async (files) => {
  const eslint = new ESLint()
  const isIgnored = await Promise.all(
    files.map((file) => {
      return eslint.isPathIgnored(file)
    })
  )
  const filteredFiles = files.filter((_, i) => !isIgnored[i])
  return filteredFiles.join(' ')
}

export default {
  '**/*.{ts,tsx,js,jsx}': async (files) => {
    const filesToLint = await removeIgnoredFiles(files)
    return [`eslint --max-warnings=0 ${filesToLint}`]
  },
}
```

#### ESLint >= 8.51.0 && [Flat ESLint config](https://eslint.org/docs/latest/use/configure/configuration-files-new)

[Permalink: ESLint >= 8.51.0 && Flat ESLint config](https://github.com/lint-staged/lint-staged#eslint--8510--flat-eslint-config)

Click to expand

ESLint v8.51.0 introduced [`--no-warn-ignored` CLI flag](https://eslint.org/docs/latest/use/command-line-interface#--no-warn-ignored). It suppresses the `warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override` warning, so manually ignoring files via `eslint.isPathIgnored` is no longer necessary.

```
{
  "*.js": "eslint --max-warnings=0 --no-warn-ignored"
}
```

**NOTE:**`--no-warn-ignored` flag is only available when [Flat ESLint config](https://eslint.org/docs/latest/use/configure/configuration-files-new) is used.

### How can I resolve TypeScript (`tsc`) ignoring `tsconfig.json` when `lint-staged` runs via Husky hooks?

[Permalink: How can I resolve TypeScript (tsc) ignoring tsconfig.json when lint-staged runs via Husky hooks?](https://github.com/lint-staged/lint-staged#how-can-i-resolve-typescript-tsc-ignoring-tsconfigjson-when-lint-staged-runs-via-husky-hooks)

Click to expand

When running `lint-staged` via Husky hooks, TypeScript may ignore `tsconfig.json`, leading to errors like:

> **TS17004:** Cannot use JSX unless the '--jsx' flag is provided.
> **TS1056:** Accessors are only available when targeting ECMAScript 5 and higher.

See issue [#825](https://github.com/lint-staged/lint-staged/issues/825) for more details.

#### Root Cause

[Permalink: Root Cause](https://github.com/lint-staged/lint-staged#root-cause)

1. `lint-staged` automatically passes matched staged files as arguments to commands.
2. Certain input files can cause TypeScript to ignore `tsconfig.json`. For more details, see this TypeScript issue: [Allow tsconfig.json when input files are specified](https://github.com/microsoft/TypeScript/issues/27379).

#### Workaround: Use a [function signature](https://github.com/lint-staged/lint-staged?tab=readme-ov-file\#example-run-tsc-on-changes-to-typescript-files-but-do-not-pass-any-filename-arguments) for the `tsc` command

[Permalink: Workaround: Use a function signature for the tsc command](https://github.com/lint-staged/lint-staged#workaround-use-a-function-signature-for-the-tsc-command)

As suggested by @antoinerousseau in [#825 (comment)](https://github.com/lint-staged/lint-staged/issues/825#issuecomment-620018284), using a function prevents `lint-staged` from appending file arguments:

**Before:**

```
// package.json

"lint-staged": {
    "*.{ts,tsx}":[\
      "tsc --noEmit",\
      "prettier --write"\
    ]
  }
```

**After:**

```
// lint-staged.config.js
module.exports = {
  '*.{ts,tsx}': [() => 'tsc --noEmit', 'prettier --write'],
}
```

## About

🚫💩 — Run tasks like formatters and linters against staged git files

[www.npmjs.com/package/lint-staged](https://www.npmjs.com/package/lint-staged)

### Topics

[developer-experience](https://github.com/topics/developer-experience) [eslint](https://github.com/topics/eslint) [git](https://github.com/topics/git) [linter](https://github.com/topics/linter) [stage-files](https://github.com/topics/stage-files) [stylelint](https://github.com/topics/stylelint) [workflow](https://github.com/topics/workflow)

### Resources

[Readme](https://github.com/lint-staged/lint-staged#readme-ov-file)

[MIT license](https://github.com/lint-staged/lint-staged#MIT-1-ov-file)

### Contributing

[Contributing](https://github.com/lint-staged/lint-staged#contributing-ov-file)

[Activity](https://github.com/lint-staged/lint-staged/activity)

[Custom properties](https://github.com/lint-staged/lint-staged/custom-properties)

### Stars

**14.7k** stars

### Watchers

**37** watching

### Forks

[**472** forks](https://github.com/lint-staged/lint-staged/forks)

[Report repository](https://github.com/contact/report-content?content_url=https%3A%2F%2Fgithub.com%2Flint-staged%2Flint-staged&report=lint-staged+%28user%29)

## Releases

## Sponsor this project

## Used by

## Contributors

## Languages

You can’t perform that action at this time.

──────── [TRUNCATED] ────────
Showing 37,410 chars (head) + 12,432 chars (tail) of 68,664 total clean characters.
Full text saved to: /opt/data/cache/web/github.com-68947ab54e.md
To read the omitted middle: read_file path="/opt/data/cache/web/github.com-68947ab54e.md" offset=578 limit=200  (the file is the complete page; raise/lower offset to page through it).
─────────────────────────────

---

## Agent Navigation

### Machine endpoints
- Knowledge graph: https://pyweb.dev/api/graph.json
- Graph analysis: https://pyweb.dev/api/graph-analysis.json
- Context index: https://pyweb.dev/llms.txt
