0
# Configuration
1
2
Flexible configuration system supporting multiple file formats, glob patterns, and both simple command strings and advanced task functions.
3
4
## Capabilities
5
6
### Configuration Types
7
8
lint-staged supports multiple configuration formats and task definition patterns.
9
10
```javascript { .api }
11
type Configuration =
12
| Record<string, string | TaskFunction | GenerateTask | (string | GenerateTask)[]>
13
| GenerateTask;
14
15
type SyncGenerateTask = (stagedFileNames: string[]) => string | string[];
16
17
type AsyncGenerateTask = (stagedFileNames: string[]) => Promise<string | string[]>;
18
19
type GenerateTask = SyncGenerateTask | AsyncGenerateTask;
20
21
interface TaskFunction {
22
title: string;
23
task: (stagedFileNames: string[]) => void | Promise<void>;
24
}
25
```
26
27
### Configuration File Formats
28
29
lint-staged automatically discovers configuration from multiple file formats:
30
31
**package.json:**
32
```json
33
{
34
"lint-staged": {
35
"*.js": "eslint --fix",
36
"*.{json,md}": "prettier --write"
37
}
38
}
39
```
40
41
**.lintstagedrc.json:**
42
```json
43
{
44
"*.js": ["eslint --fix", "git add"],
45
"*.scss": "stylelint --fix",
46
"*.md": "prettier --write"
47
}
48
```
49
50
**.lintstagedrc.js:**
51
```javascript
52
export default {
53
"*.{js,ts}": ["eslint --fix", "prettier --write"],
54
"*.css": "stylelint --fix"
55
};
56
```
57
58
**lint-staged.config.js:**
59
```javascript
60
export default {
61
"*.js": (filenames) => [
62
`eslint --fix ${filenames.join(" ")}`,
63
`prettier --write ${filenames.join(" ")}`
64
]
65
};
66
```
67
68
**.lintstagedrc.yml:**
69
```yaml
70
"*.js": eslint --fix
71
"*.{json,md}": prettier --write
72
```
73
74
### Simple String Commands
75
76
Basic string commands that will be executed with the list of staged files.
77
78
**Usage Examples:**
79
80
```json
81
{
82
"*.js": "eslint --fix",
83
"*.css": "stylelint --fix",
84
"*.{json,yml,yaml}": "prettier --write",
85
"*.md": "markdownlint --fix"
86
}
87
```
88
89
**With multiple commands:**
90
```json
91
{
92
"*.js": ["eslint --fix", "prettier --write", "git add"]
93
}
94
```
95
96
> **Note**: Using `git add` in task commands is deprecated. All modifications made by tasks are automatically added to the git commit index, so `git add` commands are unnecessary and will show a deprecation warning.
97
98
### Generate Task Functions
99
100
Functions that receive staged filenames and return command strings dynamically.
101
102
```javascript { .api }
103
/**
104
* Synchronous task generator
105
* @param stagedFileNames - Array of staged file paths
106
* @returns Command string or array of command strings
107
*/
108
type SyncGenerateTask = (stagedFileNames: string[]) => string | string[];
109
110
/**
111
* Asynchronous task generator
112
* @param stagedFileNames - Array of staged file paths
113
* @returns Promise resolving to command string or array of command strings
114
*/
115
type AsyncGenerateTask = (stagedFileNames: string[]) => Promise<string | string[]>;
116
```
117
118
**Usage Examples:**
119
120
```javascript
121
// Simple generate task
122
export default {
123
"*.js": (filenames) => `eslint --fix ${filenames.join(" ")}`
124
};
125
126
// Multiple commands from generate task
127
export default {
128
"*.js": (filenames) => [
129
`eslint --fix ${filenames.join(" ")}`,
130
`prettier --write ${filenames.join(" ")}`,
131
"git add ."
132
]
133
};
134
135
// Async generate task
136
export default {
137
"*.ts": async (filenames) => {
138
const hasTests = filenames.some(f => f.includes('.test.'));
139
const commands = [`tsc --noEmit ${filenames.join(" ")}`];
140
141
if (hasTests) {
142
commands.push("npm test");
143
}
144
145
return commands;
146
}
147
};
148
149
// Conditional logic
150
export default {
151
"*.js": (filenames) => {
152
const commands = [`eslint --fix ${filenames.join(" ")}`];
153
154
// Only run Prettier on non-minified files
155
const nonMinified = filenames.filter(f => !f.includes('.min.'));
156
if (nonMinified.length > 0) {
157
commands.push(`prettier --write ${nonMinified.join(" ")}`);
158
}
159
160
return commands;
161
}
162
};
163
```
164
165
### Task Function Objects
166
167
Advanced task definitions with custom titles and programmatic execution.
168
169
```javascript { .api }
170
interface TaskFunction {
171
/** Display title for the task */
172
title: string;
173
/** Task execution function */
174
task: (stagedFileNames: string[]) => void | Promise<void>;
175
}
176
```
177
178
**Usage Examples:**
179
180
```javascript
181
import { exec } from "child_process";
182
import { promisify } from "util";
183
184
const execAsync = promisify(exec);
185
186
export default {
187
"*.js": {
188
title: "Linting JavaScript files",
189
task: async (filenames) => {
190
await execAsync(`eslint --fix ${filenames.join(" ")}`);
191
console.log(`Linted ${filenames.length} files`);
192
}
193
},
194
195
"*.css": {
196
title: "Formatting CSS",
197
task: async (filenames) => {
198
for (const filename of filenames) {
199
await execAsync(`stylelint --fix "${filename}"`);
200
}
201
}
202
}
203
};
204
```
205
206
### Glob Patterns
207
208
lint-staged uses micromatch for glob pattern matching with support for advanced patterns.
209
210
**Basic Patterns:**
211
```json
212
{
213
"*.js": "eslint --fix",
214
"*.{css,scss}": "stylelint --fix",
215
"*.{json,yml,yaml}": "prettier --write"
216
}
217
```
218
219
**Advanced Patterns:**
220
```json
221
{
222
"src/**/*.{js,ts}": "eslint --fix",
223
"!src/**/*.test.js": "echo 'Skipping test files'",
224
"packages/*/src/**/*.ts": "tsc --noEmit",
225
"**/*.{spec,test}.{js,ts}": "jest --findRelatedTests"
226
}
227
```
228
229
**Negation Patterns:**
230
```json
231
{
232
"*.js": "eslint --fix",
233
"!dist/**": "echo 'This will never run'",
234
"src/**/*.js": ["eslint --fix", "prettier --write"],
235
"!src/**/*.min.js": "echo 'Skip minified files'"
236
}
237
```
238
239
### Configuration Loading
240
241
lint-staged automatically discovers configuration files in the following priority order (first found wins):
242
243
1. `.lintstagedrc.js` (ES module or CommonJS)
244
2. `.lintstagedrc.json`
245
3. `.lintstagedrc.yml` or `.lintstagedrc.yaml`
246
4. `lint-staged.config.js`
247
5. `"lint-staged"` field in `package.json`
248
249
Configuration discovery stops at the first file found. Use `--config` flag or the `configPath` option to override automatic discovery.
250
251
**Programmatic configuration:**
252
```javascript
253
import lintStaged from "lint-staged";
254
255
// Override automatic discovery
256
const success = await lintStaged({
257
config: {
258
"*.js": "eslint --fix",
259
"*.css": "stylelint --fix"
260
}
261
});
262
263
// Use specific config file
264
const success = await lintStaged({
265
configPath: "./custom-lint-staged.config.js"
266
});
267
```
268
269
### Complex Configuration Examples
270
271
**Monorepo Configuration:**
272
```javascript
273
export default {
274
"packages/frontend/**/*.{js,ts,tsx}": [
275
"eslint --fix",
276
"prettier --write"
277
],
278
"packages/backend/**/*.js": [
279
"eslint --fix",
280
"npm run test:unit --workspace=backend"
281
],
282
"packages/shared/**/*.ts": [
283
"tsc --noEmit --project packages/shared/tsconfig.json",
284
"prettier --write"
285
],
286
"*.{json,yml,yaml}": "prettier --write",
287
"*.md": "markdownlint --fix"
288
};
289
```
290
291
**Conditional Task Execution:**
292
```javascript
293
import { existsSync } from "fs";
294
295
export default {
296
"*.{js,ts}": (filenames) => {
297
const commands = [];
298
299
// Always run ESLint
300
commands.push(`eslint --fix ${filenames.join(" ")}`);
301
302
// Run TypeScript check if tsconfig exists
303
if (existsSync("tsconfig.json")) {
304
commands.push("tsc --noEmit");
305
}
306
307
// Run tests for test files
308
const testFiles = filenames.filter(f => f.includes(".test.") || f.includes(".spec."));
309
if (testFiles.length > 0) {
310
commands.push(`jest ${testFiles.join(" ")}`);
311
}
312
313
// Format all files
314
commands.push(`prettier --write ${filenames.join(" ")}`);
315
316
return commands;
317
}
318
};
319
```
320
321
**Performance-Optimized Configuration:**
322
```javascript
323
export default {
324
// Chunk large numbers of files
325
"*.js": (filenames) => {
326
const chunks = [];
327
const chunkSize = 10;
328
329
for (let i = 0; i < filenames.length; i += chunkSize) {
330
const chunk = filenames.slice(i, i + chunkSize);
331
chunks.push(`eslint --fix ${chunk.join(" ")}`);
332
}
333
334
return chunks;
335
},
336
337
// Separate commands for different file types
338
"*.css": "stylelint --fix",
339
"*.scss": "sass-lint --fix",
340
"*.less": "lesshint --fix"
341
};
342
```