eslint vs prettier vs semistandard vs standard vs xo
JavaScript 代码质量与格式化工具选型指南
eslintprettiersemistandardstandardxo类似的npm包:

JavaScript 代码质量与格式化工具选型指南

eslintprettiersemistandardstandardxo 都是用于提升 JavaScript 项目代码质量和一致性的工具,但它们在设计哲学、功能边界和配置灵活性上存在显著差异。eslint 是一个高度可配置的静态分析工具,专注于发现潜在错误和强制编码规范;prettier 则是一个“有主见”的代码格式化器,通过自动重写代码结构来消除风格争议;而 semistandardstandardxo 均属于“零配置”风格的 lint 工具,它们在 eslint 基础上封装了预设规则,以减少团队配置成本。这些工具常被组合使用(如 eslint + prettier),也可独立运行,选择取决于团队对控制粒度、自动化程度和维护负担的权衡。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
eslint027,2912.91 MB1118 天前MIT
prettier051,9368.6 MB1,4312 个月前MIT
semistandard01,41547.6 kB03 年前MIT
standard029,430164 kB1282 年前MIT
xo07,972114 kB93 个月前MIT

JavaScript 代码质量与格式化工具深度对比:eslint、prettier、semistandard、standard 与 xo

在现代前端工程中,保持代码一致性和避免常见错误是团队协作的基础。eslintprettiersemistandardstandardxo 是五种主流工具,但它们解决的问题层次不同 —— 有的专注逻辑错误检测,有的只管代码排版,有的则试图“全包”。本文从真实开发场景出发,深入比较它们的核心机制、适用边界和组合策略。

🔍 核心职责:谁做什么?

首先明确:eslint 是 linter(静态分析器),prettier 是 formatter(格式化器),其余三者是基于前两者封装的“一体化”方案

  • eslint:检查代码中的潜在 bug、未使用变量、类型不匹配等,规则可开启/关闭/自定义。
  • prettier:只关心代码怎么“看起来”,比如括号位置、换行、空格,输出完全由算法决定,不提供选项。
  • standard / semistandard / xo:内部调用 eslint(有时也集成 prettier),提供一套固定规则,目标是“开箱即用”。

💡 关键区别:linter 能发现 const x = 1; console.log(y); 这样的未声明变量错误,formatter 只会把这段代码缩进对齐,但不会报错。

⚙️ 配置自由度:从零配置到完全掌控

standardsemistandard:完全不可配置

这两个工具坚持“约定优于配置”理念,不允许任何规则覆盖。你只能接受它的全部规则,或不用。

// standard 规则示例:必须用单引号、不能有分号、2 空格缩进
const greeting = 'hello'; // ✅
const message = "world"; // ❌ 报错:字符串必须用单引号
console.log(greeting)   // ❌ 报错:缺少分号(standard 要求无分号,但此处因换行被解析为两个语句)

semistandardstandard 几乎相同,唯一区别是允许(甚至要求)使用分号

// semistandard 规则示例
const greeting = 'hello'; // ✅ 必须加分号
const message = "world"; // ❌ 同样报错:必须用单引号

📌 注意:semistandard 的 GitHub 仓库近年更新极少,官方文档也未明确说明维护状态,新项目应谨慎评估。

xo:有限配置 + 现代默认值

xo 在“零配置”和“可定制”之间取得平衡。它提供合理的现代 JavaScript 默认规则(如支持 top-level await、ES2023 语法),允许通过 package.jsonxo 字段局部覆盖规则

// package.json
{
  "xo": {
    "semicolon": false,
    "space": true,
    "rules": {
      "unicorn/no-array-for-each": "off"
    }
  }
}

默认情况下,xo 会自动格式化代码(内部调用 prettier),并修复可自动修正的问题(如未使用变量)。

eslint:完全可编程

eslint 的核心优势是细粒度控制。你可以逐条启用/禁用规则,设置错误级别(error/warn/off),甚至编写自定义规则。

// .eslintrc.js
module.exports = {
  extends: ['eslint:recommended', 'plugin:react/recommended'],
  rules: {
    'no-console': 'warn',
    'react/prop-types': 'off'
  },
  parserOptions: { ecmaVersion: 2022 }
};

这种灵活性使其成为大型项目的首选,但也意味着更高的初始配置成本。

prettier:格式即法律

prettier 的哲学是“不要讨论格式,我来决定”。它只提供极少数选项(如 printWidthtabWidth),一旦运行,代码结构会被强制重写。

// 输入代码
function greet( name, age ) { return 'Hello ' + name + ', you are ' + age + ' years old.'; }

// prettier 输出(默认配置)
function greet(name, age) {
  return 'Hello ' + name + ', you are ' + age + ' years old.';
}

你无法配置“函数参数是否换行”或“对象字面量是否多行”——算法根据 printWidth 自动判断。

🤝 组合使用:现实中的最佳实践

在专业项目中,eslint + prettier 是事实标准组合。原因很简单:

  • eslint 负责逻辑正确性(如变量作用域、API 使用)
  • prettier 负责视觉一致性(如缩进、换行)

但两者可能冲突(例如 eslint 要求对象末尾逗号,prettier 有自己的逗号规则)。解决方案是使用 eslint-config-prettier 关闭所有与 prettier 冲突的 eslint 规则:

// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier' // 必须放在最后,以覆盖其他配置中的格式规则
  ],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': 'error' // 将 prettier 错误作为 eslint 错误报告
  }
};

standardsemistandardxo 本质上是对这种组合的“封装简化版”:

  • standard = eslint (固定规则集) + 内置格式建议(但非 prettier
  • xo = eslint + prettier + 现代默认配置

🧪 自动修复能力对比

所有工具都支持 --fix 自动修复部分问题,但能力范围不同:

工具可修复问题类型示例
eslint规则允许的逻辑/风格问题添加缺失分号、替换 varlet
prettier所有格式问题重排换行、调整缩进、统一引号
standard有限修复(基于其 eslint 规则)移除分号、修正缩进
semistandardstandard,但保留分号添加分号、修正缩进
xoeslint 问题 + prettier 格式eslint + prettier 组合
# 各工具的修复命令
npx eslint --fix src/
npx prettier --write src/
npx standard --fix
npx semistandard --fix
npx xo --fix

⚠️ 注意:standardsemistandard 的修复能力较弱,对于复杂格式问题(如长函数参数换行)可能无法处理,而 prettierxo 能完美解决。

🧩 对 TypeScript 和现代语法的支持

  • eslint:通过 @typescript-eslint/parser 和插件支持 TS,需手动配置。
  • prettier:原生支持 TS、JSX、Flow 等,无需额外配置。
  • standard / semistandard不支持 TypeScript,仅限 JavaScript。
  • xo原生支持 TypeScript,默认启用 TS 解析,只需安装 typescript 依赖。
// TypeScript 示例(xo 可直接处理)
const greet = (name: string): string => `Hello ${name}`;

若项目使用 TypeScript,standardsemistandard 应直接排除。

🛠️ 集成开发体验(IDE 支持)

所有工具均有主流编辑器插件(VS Code、WebStorm 等),但体验略有差异:

  • eslint + prettier:需分别安装插件,配置保存时自动修复(需设置 editor.codeActionsOnSave)。
  • xo:提供专用 VS Code 插件 xo,保存时自动格式化和修复,开箱即用。
  • standard / semistandard:有对应插件,但因规则不可调,错误提示无法忽略特定行(除非用 // standard-disable-next-line 注释,但支持有限)。

📊 选型决策树

根据项目需求快速选择:

  1. 项目使用 TypeScript?

    • 是 → 排除 standard/semistandard,考虑 xoeslint+prettier
    • 否 → 继续
  2. 团队能否接受完全不可配置的规则?

    • 是 → 小项目用 standard(无分号)或 semistandard(有分号)
    • 否 → 考虑 xo(有限配置)或 eslint+prettier(完全控制)
  3. 需要严格控制代码质量(如禁止特定 API)?

    • 是 → 必须用 eslint(可自定义规则)
    • 否 → xo 可能满足需求
  4. 极度厌恶格式讨论,追求自动化?

    • 是 → prettier(单独或通过 xo)是必选项

💎 总结:没有银弹,只有权衡

  • eslint:适合需要精细控制、长期维护的大型项目,学习曲线陡峭但回报高。
  • prettier:应作为格式化基础组件,几乎适用于所有项目,单独使用或与 linter 配合。
  • standard / semistandard:仅推荐给小型 JS 项目且团队完全认同其规则;semistandard 维护状态存疑,新项目慎用。
  • xo:现代 JS/TS 项目的优秀“中间选项”,平衡了开箱即用和必要灵活性,特别适合中等规模团队。

最终,工具只是手段。清晰的代码、可维护的架构、高效的协作流程,远比选择哪个 linter 更重要。但在达成这些目标的路上,选对工具能少走很多弯路。

如何选择: eslint vs prettier vs semistandard vs standard vs xo

  • eslint:

    选择 eslint 如果你需要对代码质量规则进行精细控制,例如自定义错误级别、集成特定框架(如 React、TypeScript)的插件,或在大型项目中逐步推行规范。它适合需要长期演进、多人协作且对代码健壮性要求高的工程,但需投入时间配置和维护规则集。

  • prettier:

    选择 prettier 如果你希望彻底消除团队在代码格式(如缩进、引号、换行)上的争论,并通过自动化格式化提升一致性。它不检查逻辑错误,仅处理代码外观,因此通常与 eslint 配合使用。适合追求开发效率、减少 PR 中格式讨论的团队。

  • semistandard:

    选择 semistandard 如果你偏好 Standard 规范但希望保留分号。它是 standard 的一个分支,规则几乎完全相同,仅在是否强制省略分号这一点上不同。适合已有使用分号习惯、又想快速采用一套成熟规范的团队,但需注意其社区活跃度较低。

  • standard:

    选择 standard 如果你希望零配置地启用一套广泛接受的 JavaScript 风格(如无分号、双引号转单引号、2 空格缩进),并愿意接受其不可定制的限制。它内置了基础 lint 规则和格式建议,适合小型项目或希望快速启动的原型开发,但在大型项目中可能因缺乏灵活性而受限。

  • xo:

    选择 xo 如果你需要比 standard 更现代、更严格的默认规则(如支持 ES2023、TypeScript、自动修复),同时仍保持低配置开销。它基于 eslintprettier 构建,提供合理的默认值并允许局部覆盖,适合追求现代化 JavaScript 实践且不愿从头配置 linting 的中等规模团队。

eslint的README

npm version Downloads Build Status
Open Collective Backers Open Collective Sponsors

ESLint

Website | Configure ESLint | Rules | Contribute to ESLint | Report Bugs | Code of Conduct | X | Discord | Mastodon | Bluesky

ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:

  • ESLint uses Espree for JavaScript parsing.
  • ESLint uses an AST to evaluate patterns in code.
  • ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime.

Table of Contents

  1. Installation and Usage
  2. Configuration
  3. Version Support
  4. Code of Conduct
  5. Filing Issues
  6. Frequently Asked Questions
  7. Releases
  8. Security Policy
  9. Semantic Versioning Policy
  10. ESM Dependencies
  11. License
  12. Team
  13. Sponsors
  14. Technology Sponsors

Installation and Usage

Prerequisites

To use ESLint, you must have Node.js (^20.19.0, ^22.13.0, or >=24) installed and built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)

If you use ESLint's TypeScript type definitions, TypeScript 5.3 or later is required.

npm Installation

You can install and configure ESLint using this command:

npm init @eslint/config@latest

After that, you can run ESLint on any file or directory like this:

npx eslint yourfile.js

pnpm Installation

To use ESLint with pnpm, we recommend setting up a .npmrc file with at least the following settings:

auto-install-peers=true
node-linker=hoisted

This ensures that pnpm installs dependencies in a way that is more compatible with npm and is less likely to produce errors.

Configuration

You can configure rules in your eslint.config.js files as in this example:

import { defineConfig } from "eslint/config";

export default defineConfig([
	{
		files: ["**/*.js", "**/*.cjs", "**/*.mjs"],
		rules: {
			"prefer-const": "warn",
			"no-constant-binary-expression": "error",
		},
	},
]);

The names "prefer-const" and "no-constant-binary-expression" are the names of rules in ESLint. The first value is the error level of the rule and can be one of these values:

  • "off" or 0 - turn the rule off
  • "warn" or 1 - turn the rule on as a warning (doesn't affect exit code)
  • "error" or 2 - turn the rule on as an error (exit code will be 1)

The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the configuration docs).

Version Support

The ESLint team provides ongoing support for the current version and six months of limited support for the previous version. Limited support includes critical bug fixes, security issues, and compatibility issues only.

ESLint offers commercial support for both current and previous versions through our partners, Tidelift and HeroDevs.

See Version Support for more details.

Code of Conduct

ESLint adheres to the OpenJS Foundation Code of Conduct.

Filing Issues

Before filing an issue, please be sure to read the guidelines for what you're reporting:

Frequently Asked Questions

Does ESLint support JSX?

Yes, ESLint natively supports parsing JSX syntax (this must be enabled in configuration). Please note that supporting JSX syntax is not the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using eslint-plugin-react if you are using React and want React semantics.

Does Prettier replace ESLint?

No, ESLint and Prettier have different jobs: ESLint is a linter (looking for problematic patterns) and Prettier is a code formatter. Using both tools is common, refer to Prettier's documentation to learn how to configure them to work well with each other.

What ECMAScript versions does ESLint support?

ESLint has full support for ECMAScript 3, 5, and every year from 2015 up until the most recent stage 4 specification (the default). You can set your desired ECMAScript syntax and other settings (like global variables) through configuration.

What about experimental features?

ESLint's parser only officially supports the latest final ECMAScript standard. We will make changes to core rules in order to avoid crashes on stage 3 ECMAScript syntax proposals (as long as they are implemented using the correct experimental ESTree syntax). We may make changes to core rules to better work with language extensions (such as JSX, Flow, and TypeScript) on a case-by-case basis.

In other cases (including if rules need to warn on more or fewer cases due to new syntax, rather than just not crashing), we recommend you use other parsers and/or rule plugins. If you are using Babel, you can use @babel/eslint-parser and @babel/eslint-plugin to use any option available in Babel.

Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the TC39 process), we will accept issues and pull requests related to the new feature, subject to our contributing guidelines. Until then, please use the appropriate parser and plugin(s) for your experimental feature.

Which Node.js versions does ESLint support?

ESLint updates the supported Node.js versions with each major release of ESLint. At that time, ESLint's supported Node.js versions are updated to be:

  1. The most recent maintenance release of Node.js
  2. The lowest minor version of the Node.js LTS release that includes the features the ESLint team wants to use.
  3. The Node.js Current release

ESLint is also expected to work with Node.js versions released after the Node.js Current release.

Refer to the Quick Start Guide for the officially supported Node.js versions for a given ESLint release.

Where to ask for help?

Open a discussion or stop by our Discord server.

Why doesn't ESLint lock dependency versions?

Lock files like package-lock.json are helpful for deployed applications. They ensure that dependencies are consistent between environments and across deployments.

Packages like eslint that get published to the npm registry do not include lock files. npm install eslint as a user will respect version constraints in ESLint's package.json. ESLint and its dependencies will be included in the user's lock file if one exists, but ESLint's own lock file would not be used.

We intentionally don't lock dependency versions so that we have the latest compatible dependency versions in development and CI that our users get when installing ESLint in a project.

The Twilio blog has a deeper dive to learn more.

Releases

We have scheduled releases every two weeks on Friday or Saturday. You can follow a release issue for updates about the scheduling of any particular release.

Security Policy

ESLint takes security seriously. We work hard to ensure that ESLint is safe for everyone and that security issues are addressed quickly and responsibly. Read the full security policy.

Semantic Versioning Policy

ESLint follows semantic versioning. However, due to the nature of ESLint as a code quality tool, it's not always clear when a minor or major version bump occurs. To help clarify this for everyone, we've defined the following semantic versioning policy for ESLint:

  • Patch release (intended to not break your lint build)
    • A bug fix in a rule that results in ESLint reporting fewer linting errors.
    • A bug fix to the CLI or core (including formatters).
    • Improvements to documentation.
    • Non-user-facing changes such as refactoring code, adding, deleting, or modifying tests, and increasing test coverage.
    • Re-releasing after a failed release (i.e., publishing a release that doesn't work for anyone).
  • Minor release (might break your lint build)
    • A bug fix in a rule that results in ESLint reporting more linting errors.
    • A new rule is created.
    • A new option to an existing rule that does not result in ESLint reporting more linting errors by default.
    • A new addition to an existing rule to support a newly-added language feature (within the last 12 months) that will result in ESLint reporting more linting errors by default.
    • An existing rule is deprecated.
    • A new CLI capability is created.
    • New capabilities to the public API are added (new classes, new methods, new arguments to existing methods, etc.).
    • A new formatter is created.
    • eslint:recommended is updated and will result in strictly fewer linting errors (e.g., rule removals).
  • Major release (likely to break your lint build)
    • eslint:recommended is updated and may result in new linting errors (e.g., rule additions, most rule option updates).
    • A new option to an existing rule that results in ESLint reporting more linting errors by default.
    • An existing formatter is removed.
    • Part of the public API is removed or changed in an incompatible way. The public API includes:
      • Rule schemas
      • Configuration schema
      • Command-line options
      • Node.js API
      • Rule, formatter, parser, plugin APIs

According to our policy, any minor update may report more linting errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (~) in package.json e.g. "eslint": "~3.1.0" to guarantee the results of your builds.

ESM Dependencies

Since ESLint is a CommonJS package, there are restrictions on which ESM-only packages can be used as dependencies.

Packages that are controlled by the ESLint team and have no external dependencies can be safely loaded synchronously using require(esm) and therefore used in any contexts.

For external packages, we don't use require(esm) because a package could add a top-level await and thus break ESLint. We can use an external ESM-only package only in case it is needed only in asynchronous code, in which case it can be loaded using dynamic import().

These policies don't apply to packages intended for our own usage only, such as eslint-config-eslint.

License

MIT License

Copyright OpenJS Foundation and other contributors, <www.openjsf.org>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Team

These folks keep the project moving and are resources for help.

Technical Steering Committee (TSC)

The people who manage releases, review feature requests, and meet regularly to ensure ESLint is properly maintained.

Nicholas C. Zakas's Avatar
Nicholas C. Zakas
Francesco Trotta's Avatar
Francesco Trotta
Milos Djermanovic's Avatar
Milos Djermanovic

Reviewers

The people who review and implement new features.

唯然's Avatar
唯然
Nitin Kumar's Avatar
Nitin Kumar

Committers

The people who review and fix bugs and help triage issues.

fnx's Avatar
fnx
Josh Goldberg ✨'s Avatar
Josh Goldberg ✨
Sweta Tanwar's Avatar
Sweta Tanwar
Tanuj Kanti's Avatar
Tanuj Kanti
lumir's Avatar
lumir
Pixel998's Avatar
Pixel998

Website Team

Team members who focus specifically on eslint.org

Amaresh  S M's Avatar
Amaresh S M
Harish's Avatar
Harish
Percy Ma's Avatar
Percy Ma

Sponsors

The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. Become a Sponsor to get your logo on our READMEs and website.

Platinum Sponsors

Automattic

Gold Sponsors

Qlty Software

Silver Sponsors

Vite Liftoff StackBlitz

Bronze Sponsors

Cybozu SAP CrawlJobs Syntax Depot Icons8 Discord GitBook HeroCoders Citadel AI

Technology Sponsors

Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.

Netlify Algolia 1Password