0
# Configuration
1
2
XO supports multiple configuration methods including flat config files, CLI options, and programmatic configuration. The configuration system is built on top of ESLint's flat config format with XO-specific extensions.
3
4
## Capabilities
5
6
### XO Configuration Options
7
8
Core configuration options that control XO's linting behavior.
9
10
```typescript { .api }
11
interface XoConfigOptions {
12
/**
13
* Use spaces for indentation
14
* - boolean: true for 2 spaces, false for tabs
15
* - number: specific number of spaces
16
* - string: parsed as boolean or number
17
* - undefined: use default (tabs)
18
*/
19
space?: Space;
20
21
/** Use semicolons at the end of statements */
22
semicolon?: boolean;
23
24
/**
25
* Use Prettier to format code
26
* - true: Enable Prettier formatting
27
* - 'compat': Disable conflicting rules for separate Prettier usage
28
*/
29
prettier?: boolean | 'compat';
30
31
/** Add React support and React-specific linting rules */
32
react?: boolean;
33
34
/** Files to ignore, can be a glob pattern or array of patterns */
35
ignores?: string | string[];
36
}
37
38
// Utility type for space configuration
39
type Space = boolean | number | string | undefined;
40
```
41
42
### Flat Config Items
43
44
XO extends ESLint's flat config format with additional options.
45
46
```typescript { .api }
47
interface XoConfigItem extends XoConfigOptions {
48
/**
49
* Glob patterns indicating files this configuration applies to
50
* If not specified, applies to all files
51
*/
52
files?: string | string[];
53
54
/**
55
* Glob patterns indicating files this configuration should NOT apply to
56
* Takes precedence over files patterns
57
*/
58
ignores?: string | string[];
59
60
// Inherits all ESLint Linter.Config properties:
61
// languageOptions, plugins, rules, settings, etc.
62
}
63
64
type FlatXoConfig = XoConfigItem | XoConfigItem[];
65
```
66
67
### Linter Options
68
69
Options that control the linter's behavior and execution context.
70
71
```typescript { .api }
72
interface LinterOptions {
73
/** Current working directory to use for relative paths */
74
cwd: string;
75
76
/** Write fixes to the files automatically */
77
fix?: boolean;
78
79
/** Path to the file being linted (required for lintText) */
80
filePath?: string;
81
82
/** Show only errors and NOT warnings */
83
quiet?: boolean;
84
85
/**
86
* Auto-configure type-aware linting on unincluded TypeScript files
87
* Ensures TypeScript files are linted with type-aware parser
88
*/
89
ts?: boolean;
90
91
/** Custom path to config file to use for the linter */
92
configPath?: string;
93
}
94
```
95
96
### Text Linting Options
97
98
Options specific to linting text content rather than files.
99
100
```typescript { .api }
101
interface LintTextOptions {
102
/** Path to the file being linted (used for rule context) */
103
filePath: string;
104
105
/** Warn if the file is ignored by configuration */
106
warnIgnored?: boolean;
107
}
108
```
109
110
## Configuration File Formats
111
112
### Flat Config (Recommended)
113
114
Create a `xo.config.js` file in your project root:
115
116
```javascript
117
// xo.config.js
118
export default [
119
{
120
space: 2,
121
semicolon: true,
122
prettier: false
123
},
124
{
125
files: ["src/**/*.{js,ts}"],
126
react: true,
127
prettier: true
128
},
129
{
130
files: ["test/**/*.js"],
131
space: 4,
132
rules: {
133
// Custom ESLint rules
134
"no-console": "off"
135
}
136
},
137
{
138
ignores: ["dist/**", "coverage/**"]
139
}
140
];
141
```
142
143
### TypeScript Config
144
145
```typescript
146
// xo.config.ts
147
import type { FlatXoConfig } from "xo";
148
149
const config: FlatXoConfig = [
150
{
151
space: 2,
152
semicolon: true,
153
languageOptions: {
154
parserOptions: {
155
project: "./tsconfig.json"
156
}
157
}
158
},
159
{
160
files: ["**/*.tsx"],
161
react: true,
162
prettier: true
163
}
164
];
165
166
export default config;
167
```
168
169
### Per-Directory Configuration
170
171
```javascript
172
// xo.config.js
173
export default [
174
// Global defaults
175
{
176
space: 2,
177
semicolon: true
178
},
179
180
// Frontend specific
181
{
182
files: ["frontend/**/*.{js,ts,jsx,tsx}"],
183
react: true,
184
prettier: true,
185
space: 2
186
},
187
188
// Backend specific
189
{
190
files: ["backend/**/*.{js,ts}"],
191
react: false,
192
space: 4,
193
rules: {
194
"n/no-process-env": "off"
195
}
196
},
197
198
// Test files
199
{
200
files: ["**/*.test.{js,ts}"],
201
rules: {
202
"no-console": "off"
203
}
204
}
205
];
206
```
207
208
## CLI Configuration
209
210
Override configuration via command-line options:
211
212
```bash
213
# Override space configuration
214
xo --space 4 --semicolon --react
215
216
# Use custom config file
217
xo --config ./custom-xo.config.js
218
219
# Ignore additional patterns
220
xo --ignore "temp/**" --ignore "*.generated.js"
221
```
222
223
## Programmatic Configuration
224
225
Configure XO programmatically when creating instances:
226
227
```typescript
228
import Xo from "xo";
229
230
// Basic configuration
231
const xo = new Xo(
232
{
233
cwd: process.cwd(),
234
fix: true,
235
quiet: false
236
},
237
{
238
space: 2,
239
semicolon: true,
240
react: true,
241
ignores: ["dist/**", "coverage/**"]
242
}
243
);
244
245
// Advanced configuration with custom rules
246
const advancedXo = new Xo(
247
{ cwd: "./src", fix: false },
248
{
249
space: 4,
250
prettier: "compat",
251
// Configuration will be merged with defaults
252
}
253
);
254
```
255
256
## Configuration Resolution
257
258
XO resolves configuration in the following order (later options override earlier ones):
259
260
1. **Default XO configuration**: Built-in opinionated defaults
261
2. **Flat config file**: `xo.config.js`, `xo.config.ts`, etc.
262
3. **Base XO config**: Passed to constructor or CLI
263
4. **CLI options**: Command-line flags
264
5. **Environment-specific**: GitHub Actions auto-quiet mode
265
266
## TypeScript Configuration
267
268
XO automatically handles TypeScript configuration:
269
270
```typescript
271
// xo.config.ts
272
export default [
273
{
274
// TypeScript files automatically get type-aware linting
275
files: ["**/*.{ts,tsx}"],
276
languageOptions: {
277
parserOptions: {
278
project: true, // Use nearest tsconfig.json
279
tsconfigRootDir: import.meta.dirname
280
}
281
}
282
},
283
{
284
// Override for specific files
285
files: ["scripts/**/*.ts"],
286
languageOptions: {
287
parserOptions: {
288
project: "./scripts/tsconfig.json"
289
}
290
}
291
}
292
];
293
```
294
295
## Prettier Integration
296
297
Configure Prettier integration:
298
299
```javascript
300
// xo.config.js with Prettier
301
export default [
302
{
303
prettier: true,
304
space: 2,
305
semicolon: true,
306
// XO will validate Prettier config matches XO options
307
},
308
{
309
// Compatibility mode - let Prettier handle formatting separately
310
files: ["formatted/**/*.js"],
311
prettier: "compat"
312
}
313
];
314
```
315
316
## Ignore Patterns
317
318
Configure file ignoring:
319
320
```javascript
321
// xo.config.js
322
export default [
323
{
324
// Global ignores (no files specified)
325
ignores: [
326
"dist/**",
327
"coverage/**",
328
"node_modules/**",
329
"*.min.js"
330
]
331
},
332
{
333
// Conditional ignores
334
files: ["src/**/*.js"],
335
ignores: ["src/**/*.generated.js"]
336
}
337
];
338
```
339
340
## Default Configuration
341
342
XO includes comprehensive defaults:
343
344
```typescript { .api }
345
// Default ignore patterns
346
const defaultIgnores = [
347
"**/node_modules/**",
348
"**/bower_components/**",
349
"flow-typed/**",
350
"coverage/**",
351
"{tmp,temp}/**",
352
"**/*.min.js",
353
"vendor/**",
354
"dist/**",
355
"tap-snapshots/*.{cjs,js}"
356
];
357
358
// Default file extensions
359
const jsExtensions = ["js", "jsx", "mjs", "cjs"];
360
const tsExtensions = ["ts", "tsx", "cts", "mts"];
361
const allExtensions = [...jsExtensions, ...tsExtensions];
362
```
363
364
## Configuration Conversion
365
366
Convert XO config to ESLint config:
367
368
```typescript
369
import { xoToEslintConfig } from "xo";
370
371
const xoConfig = [
372
{ space: 2, semicolon: true, react: true }
373
];
374
375
const eslintConfig = xoToEslintConfig(xoConfig, {
376
prettierOptions: { semi: true, tabWidth: 2 }
377
});
378
379
// Use with ESLint directly
380
import { ESLint } from "eslint";
381
const eslint = new ESLint({ overrideConfig: eslintConfig });
382
```
383
384
## Environment-Specific Configuration
385
386
```javascript
387
// xo.config.js
388
const isCI = process.env.CI === "true";
389
const isDevelopment = process.env.NODE_ENV === "development";
390
391
export default [
392
{
393
space: 2,
394
semicolon: true,
395
// Adjust for CI environment
396
...(isCI && {
397
quiet: true,
398
// More strict rules in CI
399
rules: {
400
"no-console": "error"
401
}
402
}),
403
// Development-friendly rules
404
...(isDevelopment && {
405
rules: {
406
"no-console": "warn",
407
"no-debugger": "warn"
408
}
409
})
410
}
411
];
412
```