MCPcopy
hub / github.com/xojs/xo

github.com/xojs/xo @v3.0.2 sqlite

repository ↗ · DeepWiki ↗ · release v3.0.2 ↗
68 symbols 270 edges 25 files 11 documented · 16%
README

XO

JavaScript/TypeScript linter (ESLint wrapper) with great defaults

Coverage Status XO code style

Opinionated but configurable ESLint wrapper with lots of goodies included. Enforces strict and readable code. Never discuss code style on a pull request again! No decision-making. No eslint.config.js to manage. It just works!

It uses ESLint underneath, so issues regarding built-in rules should be opened over there.

XO requires your project to be ESM.

Highlights

Install

npm install xo --save-dev

You must install XO locally. You can run it directly with $ npx xo.

For framework-specific linting, see Astro, React, Svelte, and Vue.

Usage

$ xo --help

    Usage
        $ xo [<file|glob> ...]

    Options
        --fix                     Automagically fix issues
        --fix-dry-run             Automagically fix issues without saving the changes to the file system
        --reporter                Reporter to use
        --space                   Use space indent instead of tabs [Default: 2]
        --config                  Path to a XO configuration file
        --semicolon               Use semicolons [Default: true]
        --prettier                Format with prettier or turn off Prettier-conflicted rules when set to 'compat' [Default: false]
        --print-config            Print the effective ESLint config for the given file
        --version                 Print XO version
        --open                    Open files with issues in your editor
        --quiet                   Show only errors and no warnings
        --max-warnings            Number of warnings to trigger nonzero exit code [Default: -1]
        --stdin                   Validate/fix code from stdin
        --stdin-filename          Specify a filename for the --stdin option
        --ignore                  Ignore pattern globs, can be set multiple times
        --suppressions-location   Path to a custom ESLint suppressions file
        --cwd=<dir>               Working directory for files [Default: process.cwd()]

    Examples
        $ xo
        $ xo index.js
        $ xo *.js !foo.js
        $ xo --space
        $ xo --print-config=index.js
        $ echo 'const x=true' | xo --stdin --fix

    Tips
        - Add XO to your project with `npm init xo`.
        - Put options in xo.config.js instead of using flags so other tools can read it.

Default code style

Any of these can be overridden if necessary.

  • Tab indentation (or space)
  • Semicolons (or not)
  • Single-quotes
  • Trailing comma for multiline statements
  • No unused variables
  • Space after keyword if (condition) {}
  • Always === instead of ==

Check out an example and the ESLint rules.

Workflow

The recommended workflow is to add XO locally to your project and run it with the tests.

Simply run $ npm init xo (with any options) to add XO to create an xo.config.js.

Config

You can configure XO options by creating an xo.config.js or an xo.config.ts file in the root directory of your project, or you can add an xo field to your package.json. XO supports all js/ts file extensions (js,cjs,mjs,ts,cts,mts) and popular framework extensions (vue,svelte,astro) automatically. A XO config is an extension of ESLint's Flat Config. Like ESLint, an XO config exports an array of XO config objects. XO config objects extend ESLint Configuration Objects. This means all the available configuration params for ESLint also work for XO. However, XO enhances and adds extra params to the configuration objects to make them easier to work with.

Config types

XO exports the types FlatXoConfig, XoConfigItem, and other types for you to get TypeScript validation on your config files.

examples: xo.config.js

/** @type {import('xo').FlatXoConfig} */
const xoConfig = [...]

xo.config.ts

import {type FlatXoConfig} from 'xo';

const xoConfig: FlatXoConfig = [...]
export default [...] satisfies import('xo').FlatXoConfig

files

Type: string | (string | string[])[]\ Default: **/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,vue,svelte,astro}

A glob string, array of globs, or ESLint's native format (where nested arrays create AND patterns) indicating which files the config object applies to. By default XO will apply the configuration to all files. This is compatible with ESLint plugin configs, so you can spread them directly into your XO config.

Tip: If you are adding additional @typescript-eslint rules to your config, these rules will apply to JS files as well unless you separate them appropriately with the files option. @typescript-eslint rules set to 'off' or 0, however, will have no effect on JS linting.

ignores

Type: string | string[]

Some paths are ignored by default, including paths in .gitignore. Additional ignores can be added here.

Tip: For global ignores, keep ignores as the only key in the config item. You can optionally set a name property. Adding more properties will cause ignores to be scoped down to your files selection, which may have unexpected effects.

Global negated ignores are supported in both config files and the CLI for reopening XO's built-in ignored paths. This includes directory globs like !dist/**, file globs like !**/*.min.js, and literal file paths like !dist/src/index.js.

When global ignores are involved, XO uses them in this order:

  1. Built-in default ignores
  2. Global config ignores
  3. CLI ignores

XO keeps positive ignores for fast file discovery and only rechecks XO's own default-ignored paths. ESLint makes the final ignore decision.

space

Type: boolean | number\ Default: false (tab indentation)

Set it to true to get 2-space indentation or specify the number of spaces.

This option exists for pragmatic reasons, but I would strongly recommend you read “Why tabs are superior”.

semicolon

Type: boolean\ Default: true (Semicolons required)

Set it to false to enforce no-semicolon style.

prettier

Type: boolean | 'compat'\ Default: false

Format code with Prettier.

XO applies its own Prettier options:

Any options you set in a Prettier config still apply for anything XO does not configure (like printWidth or plugins), but XO's own style settings take precedence.

Compat

If the Prettier option is set to compat, instead of formatting your code automatically, XO will turn off all rules that conflict with Prettier code style and allow you to pass your formatting to the Prettier tool directly.

Astro

To lint Astro files, install eslint-plugin-astro:

npm install --save-dev eslint-plugin-astro

Then spread its recommended config in your xo.config.js:

import astroPlugin from 'eslint-plugin-astro';

const xoConfig = [
    ...astroPlugin.configs.recommended,
];

export default xoConfig;

React

To lint React files, install eslint-config-xo-react:

npm install --save-dev eslint-config-xo-react

Then spread it in your xo.config.js:

import xoReact from 'eslint-config-xo-react';

const xoConfig = [
    ...xoReact(),
];

export default xoConfig;

[!NOTE] Until eslint-plugin-react supports ESLint 10 natively, you may need to wrap the config with fixupConfigRules from @eslint/compat.

Svelte

To lint Svelte files, install eslint-plugin-svelte:

npm install --save-dev eslint-plugin-svelte

Then spread its recommended config in your xo.config.js:

import sveltePlugin from 'eslint-plugin-svelte';

const xoConfig = [
    ...sveltePlugin.configs.recommended,
];

export default xoConfig;

Vue

To lint Vue files, install eslint-plugin-vue:

npm install --save-dev eslint-plugin-vue

Then spread its recommended config in your xo.config.js:

import vuePlugin from 'eslint-plugin-vue';

const xoConfig = [
    ...vuePlugin.configs['flat/recommended'],
];

export default xoConfig;

Shareable configs

If you want to extend a shareable ESLint config or any other npm package, use xo.config.js instead of package.json, since package.json only supports serializable values and cannot import.

xo.config.js

export {default} from 'my-shareable-config';

You can also extend and override:

import myConfig from 'my-shareable-config';

export default [
    ...myConfig,
    {
        rules: {
            // Your overrides
        },
    },
];

TypeScript

XO will automatically lint TypeScript files (.ts, .mts, .cts, and .tsx) with the rules defined in eslint-config-xo-typescript#use-with-xo.

XO will handle the @typescript-eslint/parser project option automatically even if you don't have a tsconfig.json in your project.

You can opt out of XO's automatic tsconfig handling by specifying your own languageOptions.parserOptions.project, languageOptions.parserOptions.projectService, or languageOptions.parserOptions.tsconfigRootDir. Files in a config with these properties will be excluded from automatic tsconfig handling.

Usage as an ESLint Configuration

There are two different ways to use XO's rules with ESLint directly, depending on whether you use the xo CLI.

Without the xo CLI

If you don't use the xo CLI and just want XO's rules in ESLint, use eslint-config-xo. It accepts the same core style options as XO, including Prettier integration:

eslint.config.js

import eslintConfigXo from 'eslint-config-xo';

export default [
    ...eslintConfigXo({space: true, prettier: true}),
];

[!NOTE] This replaces the old xoToEslintConfig helper. For example, xoToEslintConfig([{space: true, prettier: true}]) becomes eslintConfigXo({space: true, prettier: true}). For per-file overrides, add normal ESLint config objects alongside it.

With the xo CLI (editor integration)

If you use the xo CLI but your editor only has the ESLint extension (not XO's), add an eslint.config.js that re-exports the adapter. It reads your xo.config.js and generates the matching ESLint config automatically, so your editor shows the same errors as running xo — without duplicating your config.

eslint.config.js

export {default} from 'xo/eslint-adapter';

Tips

Monorepo

Put a xo.config.js with your config at the root and do not add a config to any of your bundled packages.

Including files ignored by default

To include files that XO ignores by default, add them as negative globs in the [`ignore

Core symbols most depended-on inside this repo

lintFiles
called by 48
lib/xo.ts
lintText
called by 47
lib/xo.ts
rejectionOf
called by 30
test/helpers/rejection-of.ts
preProcessXoConfig
called by 25
lib/utils.ts
xoToEslintConfig
called by 25
lib/xo-to-eslint.ts
matchFilesForTsConfig
called by 24
lib/utils.ts
resolveXoConfig
called by 13
lib/resolve-config.ts
validateXoConfig
called by 6
lib/utils.ts

Shape

Function 48
Method 18
Class 2

Languages

TypeScript100%

Modules by API surface

lib/xo.ts38 symbols
test/eslint-adapter.test.ts5 symbols
lib/utils.ts4 symbols
lib/open-report.ts4 symbols
lib/eslint-adapter.ts3 symbols
lib/xo-to-eslint.ts2 symbols
lib/resolve-config.ts2 symbols
lib/handle-ts-files.ts2 symbols
cli.ts2 symbols
test/xo/no-use-extend-native.test.ts1 symbols
test/xo/lint-text.test.ts1 symbols
test/helpers/rejection-of.ts1 symbols

Dependencies from manifests, versioned

@sindresorhus/tsconfig8.1.0 · 1×
@types/micromatch4.0.10 · 1×
@types/node25.9.3 · 1×
arrify3.0.0 · 1×
cosmiconfig9.0.2 · 1×
dedent1.7.2 · 1×
define-lazy-prop3.0.0 · 1×
eslint10.5.0 · 1×
eslint-config-xo0.53.1 · 1×
eslint-formatter-pretty7.1.0 · 1×
eslint-plugin-vue10.9.2 · 1×
execa9.6.1 · 1×

For agents

$ claude mcp add xo \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact