xo vs semistandard vs eslint vs standard
JavaScriptコードの品質保証とスタイル強制のためのリンターツール比較
xosemistandardeslintstandard類似パッケージ:

JavaScriptコードの品質保証とスタイル強制のためのリンターツール比較

eslintsemistandardstandardxo はすべて JavaScript プロジェクトにおけるコード品質の維持やコーディング規約の自動適用を目的としたツールです。これらは静的解析(リンティング)を行い、潜在的なバグやスタイル違反を検出します。eslint は高度にカスタマイズ可能なルールエンジンを提供し、他の3つは eslint をベースにした「プリセット」または「オピニオン型」の設定として機能します。standard はセミコロン不要・2スペースインデントなど独自のスタイルを採用し、semistandard はそれに対してセミコロンを許容する変種です。xo は現代的な JavaScript(ESNext、TypeScript 対応など)に特化し、より積極的なコード修正を推奨します。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
xo408,9407,95384.6 kB505ヶ月前MIT
semistandard28,9101,41747.6 kB03年前MIT
eslint027,1772.89 MB10621時間前MIT
standard029,432164 kB1291年前MIT

JavaScript リンター戦略:eslint vs semistandard vs standard vs xo

フロントエンド開発において、コードの品質と一貫性を保つことは長期的な保守性に直結します。eslintsemistandardstandardxo はいずれもこの課題に取り組むツールですが、アプローチと適用範囲が大きく異なります。現場の実情に即して、それぞれの特性を深掘りします。

🧩 基本設計思想:柔軟性 vs 決められた道

eslint は「ルールエンジン」として設計されており、すべての設定を明示的に定義する必要があります。

  • ルールの有効/無効、エラー/警告レベル、オプションを個別に指定可能
  • .eslintrc.jseslint.config.js(Flat Config)で詳細な設定が可能
  • プラグインやカスタムルールによる拡張性が非常に高い
// eslint.config.js (Flat Config)
import js from '@eslint/js';

export default [
  js.configs.recommended,
  {
    rules: {
      'no-console': 'warn',
      'indent': ['error', 2]
    }
  }
];

standard は「設定不要」をコンセプトに、あらかじめ決められたルールセットを提供します。

  • 設定ファイル不要で即時利用可能
  • セミコロン不要、2スペースインデント、シングルクォートなど独自スタイルを強制
  • カスタマイズは基本的に非推奨(.standardrc での一部例外対応あり)
// package.json
{
  "scripts": {
    "lint": "standard"
  },
  "devDependencies": {
    "standard": "*"
  }
}

semistandardstandard の派生版で、唯一の違いは「セミコロンを許容する」点です。

  • それ以外のルール(インデント、クォートなど)は standard と同一
  • セミコロン派とノーセミコロン派の間で折衷案が必要なチーム向け
// package.json
{
  "scripts": {
    "lint": "semistandard"
  },
  "devDependencies": {
    "semistandard": "*"
  }
}

xo は「モダン JavaScript 向けのオピニオン型リンター」として設計されています。

  • ES2022+ や TypeScript、React JSX への対応が標準で含まれる
  • 自動修正(--fix)を積極的に推奨
  • 設定は package.jsonxo フィールドまたは xo.config.js で行う
// package.json
{
  "xo": {
    "semicolon": false,
    "space": true
  }
}

🔧 カスタマイズ性:自由度のトレードオフ

ルールの上書き

eslint では任意のルールを自由に上書きできます。

// .eslintrc.js
module.exports = {
  rules: {
    'no-var': 'error',
    'prefer-const': 'warn'
  }
};

standard / semistandard では公式にカスタマイズが推奨されていませんが、.eslintrc を併用することで部分的に上書き可能です(非公式なワークアラウンド)。

// .eslintrc.json(standard と併用)
{
  "extends": ["./node_modules/standard/eslintrc.json"],
  "rules": {
    "comma-dangle": "off"
  }
}

xo では overridesrules フィールドで公式にカスタマイズをサポートしています。

// xo.config.js
export default {
  rules: {
    'unicorn/filename-case': 'off'
  }
};

プラグインと統合

eslint は公式プラグイン(@typescript-eslinteslint-plugin-react など)との統合が標準的です。

// eslint.config.js
import reactPlugin from 'eslint-plugin-react';

export default [
  {
    plugins: { react: reactPlugin },
    rules: { 'react/jsx-uses-react': 'error' }
  }
];

xo は内部で eslint を使用しており、reacttypescriptvue などのサポートがビルトインされています。

// xo は package.json に "type": "module" があれば自動で ESM 対応
// TypeScript ファイルがあれば自動で型チェックを有効化

一方、standard / semistandard はプラグイン対応が限定的で、主に JavaScript のみを対象とします。

🛠️ 実行と修正:開発体験の差

自動修正機能

すべてのツールが --fix オプションをサポートしていますが、その範囲に差があります。

eslint:

npx eslint --fix src/

standard:

npx standard --fix

semistandard:

npx semistandard --fix

xo:

npx xo --fix

ただし、xo はより積極的に修正を適用し、たとえば未使用の変数を自動削除するなど、eslint のデフォルトルールよりも踏み込んだ修正を行います。

CI 統合

eslintxo は exit code を適切に返すため、CI での失敗検出が容易です。

# GitHub Actions
- run: npx eslint .
# エラーがあれば自動で job 失敗

standard / semistandard も同様ですが、出力形式が簡素なため、詳細なレポートが必要な場合は eslint + formatter の方が有利です。

🌐 実際のコード例で見る違い

以下のコードを各ツールでチェックした場合の挙動を比較します。

// sample.js
var foo = 'bar'
console.log(foo)
  • eslint(推奨ルールのみ): var の使用で警告、末尾セミコロンなしでエラー(ルール次第)
  • standard: セミコロンなしでエラー、var 使用でエラー、2スペースでない場合もエラー
  • semistandard: var 使用でエラー(セミコロンは OK)
  • xo: var 使用でエラー、末尾セミコロンなしでエラー(デフォルト設定)、さらに未使用変数なら警告

📌 選定ガイド:プロジェクトの成熟度とニーズに合わせて

新規プロジェクトで素早く始めたい

  • standard または semistandard を選ぶと、設定不要で即座に一貫したスタイルが適用されます。
  • セミコロンの有無で迷うなら、チームの好みに合わせて選択。

モダン JS / TS プロジェクト

  • xo が最もスムーズです。TypeScript や JSX のサポートが標準で含まれ、最新の構文にも追随しています。

大規模プロジェクトや複雑な要件

  • eslint が唯一の選択肢です。細かなルール調整、複数の技術スタックへの対応、カスタムルールの導入などが必須になるためです。

既存プロジェクトの段階的導入

  • eslint--init 機能で既存コードに合わせたルールを生成し、徐々に厳格化するのが現実的です。
  • standard 系は既存コードとの互換性が低く、一括修正が必要になることが多いです。

💡 最終的なアドバイス

  • 柔軟性が命eslint
  • シンプルさが正義standard(セミコロン不要)または semistandard(セミコロン可)
  • 最新技術スタックで高速開発xo

重要なのは、一度選んだツールをチーム全体で徹底し、CI で強制することです。ツール自体よりも、一貫した運用の方が品質向上に大きく貢献します。

選び方: xo vs semistandard vs eslint vs standard

  • xo:

    xo は最新の JavaScript 機能(ES2022+ や TypeScript)を積極的にサポートし、コードの現代化を促進したい場合に適しています。自動修正機能が充実しており、CI 統合もしやすい設計です。ただし、頻繁に更新されるため、安定性よりも先進性を重視するプロジェクト向きです。

  • semistandard:

    semistandard は Standard スタイルをベースにしつつ、セミコロンの使用を許容したいチーム向けです。Standard の哲学(シンプルで設定不要)を尊重しつつ、セミコロン必須派の開発者にも配慮する妥協点として有効です。既存の Standard コードベースにセミコロンを段階的に導入したい場合にも適しています。

  • eslint:

    eslint はプロジェクトの要件に完全に合わせてルールを細かく調整したい場合に最適です。大規模チームや複数のサブプロジェクトを持つモノレポ環境では、共通のカスタム設定を共有することで一貫性を保ちつつ柔軟性も確保できます。ただし、初期設定とメンテナンスにはコストがかかります。

  • standard:

    standard は「設定不要」を掲げ、最小限の構成で即座に一貫したコードスタイルを適用したい場合に選択します。新規プロジェクトで迅速に開発を始めたい、またはチーム内でスタイル議論を避けたい場合に特に有効です。ただし、ルールのカスタマイズがほぼ不可能なため、特定の規約に強く縛られることになります。

xo の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

  • Beautiful output.
  • Zero-config, but configurable when needed.
  • Enforces readable code, because you read more code than you write.
  • No need to specify file paths to lint as it lints all JS/TS files except for commonly ignored paths.
  • Flat config customization.
  • TypeScript supported by default.
  • Includes many useful ESLint plugins, like unicorn, import, ava, n and more.
  • Caches results between runs for much better performance.
  • Super simple to add XO to a project with $ npm init xo.
  • Fix many issues automagically with $ xo --fix.
  • Open all files with errors at the correct line in your editor with $ xo --open.
  • Specify indent and semicolon preferences easily without messing with the rule config.
  • Optionally use the Prettier code style or turn off all Prettier rules with the compat option.
  • Optionally use eslint-config-xo-react for easy JSX and React linting with zero config.
  • Optionally use with ESLint directly
  • Great editor plugins.

Install

npm install xo --save-dev

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

You'll need eslint-config-xo-vue for specific linting in a Vue app.

Usage

$ xo --help

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

	Options
		--fix             Automagically fix issues
		--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]
		--react           Include React specific parsing and xo-react linting rules [Default: false]
		--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
		--stdin           Validate/fix code from stdin
		--stdin-filename  Specify a filename for the --stdin option
		--ignore          Ignore pattern globs, can be set multiple times
		--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[] | undefined
Default: **/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,vue,svelte,astro}

A glob or array of glob strings which the config object will apply. By default XO will apply the configuration to all files.

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[]

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.

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.

Prettier options will be based on your Prettier config. XO will then merge your options with its own defaults:

To stick with Prettier's defaults, add this to your Prettier config:

export default {
	singleQuote: false,
	bracketSpacing: true,
};

If contradicting options are set for both Prettier and XO, an error will be thrown.

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.

react

Type: boolean
Default: false

Adds eslint-plugin-react, eslint-plugin-react-hooks, and eslint-config-xo-react to get all the React best practices applied automatically.

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

With the introduction of the ESLint flat config, many of the original goals of xo were brought into the ESLint core, and shareable configs with plugins became possible. Although we highly recommend the use of the xo cli, we understand that some teams need to rely on ESLint directly.

For these purposes, you can still get most of the features of xo by using our ESLint configuration helpers.

xoToEslintConfig

The xoToEslintConfig function is designed for use in an eslint.config.js file. It is NOT for use in an xo.config.js file. This function takes a FlatXoConfig and outputs an ESLint config object. This function will neither be able to automatically handle TS integration for you nor automatic Prettier integration. You are responsible for configuring your other tools appropriately. The xo cli, will, however, handle all of these details for you.

eslint.config.js

import xo from 'xo';

export default xo.xoToEslintConfig([{space: true, prettier: 'compat'}]);

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 ignores option:

const xoConfig = [{ignores: ['!vendor/**']}];

export default xoConfig;

FAQ

What does XO mean?

It means hugs and kisses.

Why not Standard?

The Standard style is a really cool idea. I too wish we could have one style to rule them all! But the reality is that the JS community is just too diverse and opinionated to create one code style. They also made the mistake of pushing their own style instead of the most popular one. In contrast, XO is more pragmatic and has no aspiration of being the style. My goal with XO is to make it simple to enforce consistent code style with close to no config. XO comes with my code style preference by default, as I mainly made it for myself, but everything is configurable.

Why not ESLint?

XO is based on ESLint. This project started out as just a shareable ESLint config, but it quickly grew out of that. I wanted something even simpler. Just typing xo and be done. No decision-making. No config. I also have some exciting future plans for it. However, you can still get most of the XO benefits while using ESLint directly with the ESLint shareable config.

Editor plugins

Build-system plugins

Configs

Support

Related

Badge

Show the world you're using XO → XO code style

[![XO code style](https://shields.io/badge/code_style-5ed9c7?logo=xo&labelColor=gray&logoSize=auto)](https://github.com/xojs/xo)

Or customize the badge.

You can also find some nice dynamic XO badges on badgen.net.

Team

Former