Convert Figma logo to code with AI

xojs logoxo

❤️ JavaScript/TypeScript linter (ESLint wrapper) with great defaults

7,645
291
7,645
59

Top Related Projects

29,051

🌟 JavaScript Style Guide, with linter & automatic code fixer

49,046

Prettier is an opinionated code formatter.

24,850

Find and fix problems in your JavaScript code.

5,909

:vertical_traffic_light: An extensible linter for the TypeScript language

8,975

JSHint is a tool that helps to detect errors and potential problems in your JavaScript code

3,616

JSLint, The JavaScript Code Quality and Coverage Tool

Quick Overview

XO is a JavaScript/TypeScript linter with a focus on code quality and style enforcement. It combines ESLint with a curated set of rules to provide an opinionated, zero-configuration linting experience. XO aims to help developers write clean, consistent, and error-free code with minimal setup.

Pros

  • Zero-configuration setup, works out of the box
  • Integrates well with popular editors and CI/CD pipelines
  • Supports both JavaScript and TypeScript
  • Regularly updated with the latest ESLint rules and best practices

Cons

  • Opinionated nature may not suit all coding styles or preferences
  • Limited customization options compared to raw ESLint
  • May require additional setup for complex projects or non-standard configurations

Code Examples

  1. Basic usage in a Node.js script:
// example.js
const x = 'foo'
x = 'bar' // XO will catch this reassignment error
  1. Using XO with React:
// Component.jsx
import React from 'react'

const MyComponent = ({name}) => (
  <div>Hello, {name}!</div>
)

export default MyComponent
  1. TypeScript example:
// greeter.ts
function greet(person: string): string {
  return `Hello, ${person}!`
}

console.log(greet('World'))

Getting Started

  1. Install XO in your project:
npm install --save-dev xo
  1. Add a script to your package.json:
{
  "scripts": {
    "lint": "xo"
  }
}
  1. Run XO:
npm run lint

To automatically fix issues, use:

npm run lint -- --fix

Competitor Comparisons

29,051

🌟 JavaScript Style Guide, with linter & automatic code fixer

Pros of Standard

  • Larger community and wider adoption, leading to better support and resources
  • No configuration required, promoting consistency across projects
  • Automatic formatting on save with many popular editors and IDEs

Cons of Standard

  • Less flexibility in rule customization
  • Stricter rules that may not suit all coding styles or preferences
  • Slower performance compared to XO, especially on larger codebases

Code Comparison

Standard:

function example (x, y) {
  if (x) {
    return y
  }
}

XO:

function example(x, y) {
	if (x) {
		return y;
	}
}

The main differences in this example are:

  • Space after function name in Standard, none in XO
  • No semicolons in Standard, required in XO
  • Tabs for indentation in XO, spaces in Standard

Both Standard and XO are popular JavaScript linters and style checkers. Standard focuses on simplicity and zero-configuration, while XO offers more customization options. The choice between them often depends on project requirements, team preferences, and the desired balance between strictness and flexibility in coding style enforcement.

49,046

Prettier is an opinionated code formatter.

Pros of Prettier

  • Wider language support, including CSS, HTML, and more
  • Opinionated formatting with fewer configuration options, leading to more consistent code across projects
  • Larger community and ecosystem, with integrations for many editors and tools

Cons of Prettier

  • Less flexibility in code style customization
  • May reformat code in ways that some developers find less readable
  • Can be slower on large codebases compared to XO

Code Comparison

XO:

function example (a, b) {
    return a + b;
}

Prettier:

function example(a, b) {
  return a + b;
}

Key Differences

  • XO is primarily a JavaScript/TypeScript linter with formatting capabilities, while Prettier is a dedicated code formatter for multiple languages
  • XO allows more granular control over code style rules, whereas Prettier aims for a more opinionated, consistent style
  • Prettier focuses solely on formatting, while XO includes additional linting rules for code quality and potential errors

Use Cases

  • Choose XO for projects requiring specific JavaScript/TypeScript linting rules and more control over code style
  • Opt for Prettier in multi-language projects or when seeking a low-configuration, opinionated formatter

Both tools have their strengths and can be used together in some workflows, with Prettier handling formatting and XO focusing on linting rules.

24,850

Find and fix problems in your JavaScript code.

Pros of ESLint

  • Highly configurable with extensive rule sets and plugins
  • Large community support and ecosystem
  • Supports custom parsers for non-standard JavaScript syntax

Cons of ESLint

  • More complex setup and configuration process
  • Steeper learning curve for beginners
  • Potentially slower performance due to its extensive feature set

Code Comparison

ESLint configuration example:

{
  "extends": "eslint:recommended",
  "rules": {
    "indent": ["error", 2],
    "quotes": ["error", "single"],
    "semi": ["error", "always"]
  }
}

XO configuration example:

{
  "extends": "xo",
  "space": true,
  "semicolon": false
}

ESLint offers more granular control over individual rules, while XO provides a simpler, opinionated configuration. ESLint's flexibility allows for fine-tuning of rules, but XO's approach reduces setup complexity.

Both tools aim to improve code quality and consistency, but they cater to different user preferences. ESLint is ideal for projects requiring extensive customization, while XO is better suited for those seeking a quick, opinionated setup with minimal configuration.

5,909

:vertical_traffic_light: An extensible linter for the TypeScript language

Pros of TSLint

  • More extensive rule set, offering greater customization for TypeScript projects
  • Better integration with TypeScript compiler, providing more accurate linting
  • Supports custom rules and plugins for project-specific needs

Cons of TSLint

  • Slower performance, especially on larger projects
  • Steeper learning curve due to more complex configuration options
  • Discontinued project, with official recommendation to migrate to ESLint

Code Comparison

TSLint configuration:

{
  "rules": {
    "no-unused-variable": true,
    "semicolon": [true, "always"],
    "quotemark": [true, "single"]
  }
}

XO configuration:

{
  "extends": "xo",
  "rules": {
    "semicolon": ["error", "always"],
    "quotes": ["error", "single"]
  }
}

TSLint offers more TypeScript-specific rules, while XO provides a simpler configuration with sensible defaults. XO is more lightweight and faster, making it suitable for smaller projects or those prioritizing speed. TSLint's extensive rule set and TypeScript integration make it better for large-scale TypeScript projects, despite its discontinued status. XO's simplicity and active maintenance make it a more future-proof choice for general JavaScript and TypeScript linting needs.

8,975

JSHint is a tool that helps to detect errors and potential problems in your JavaScript code

Pros of JSHint

  • Longer history and established reputation in the JavaScript community
  • More configurable with a wide range of options
  • Supports older JavaScript versions and legacy codebases

Cons of JSHint

  • Less frequent updates and slower adoption of new ECMAScript features
  • More complex configuration process
  • Lacks some modern linting features and code style enforcement capabilities

Code Comparison

JSHint configuration example:

{
  "esversion": 6,
  "node": true,
  "curly": true,
  "eqeqeq": true
}

XO configuration example:

{
  "extends": "xo",
  "space": true,
  "semicolon": false
}

XO offers a more opinionated and streamlined approach to linting, with fewer configuration options but sensible defaults. It focuses on modern JavaScript practices and enforces a consistent code style out of the box. JSHint, on the other hand, provides more granular control over linting rules but requires more setup and maintenance.

While JSHint is still widely used, especially in older projects, XO has gained popularity for its simplicity and modern approach to JavaScript linting. XO also integrates well with other tools in the JavaScript ecosystem, making it a popular choice for new projects and developers looking for a more opinionated linting solution.

3,616

JSLint, The JavaScript Code Quality and Coverage Tool

Pros of JSLint

  • Longer history and established reputation in the JavaScript community
  • Stricter coding standards, which can lead to more consistent and error-free code
  • Simpler configuration with fewer options, making it easier for beginners to use

Cons of JSLint

  • Less flexible and customizable compared to XO
  • Slower adoption of new JavaScript features and syntax
  • Smaller ecosystem and fewer integrations with modern development tools

Code Comparison

JSLint:

/*jslint browser */
function example(x) {
    "use strict";
    return x + 1;
}

XO:

function example(x) {
	return x + 1;
}

JSLint requires explicit strict mode and encourages JSLint-specific comments, while XO focuses on modern JavaScript practices and doesn't require additional syntax. XO's default configuration is more lenient, allowing for a smoother integration into existing projects.

Both tools aim to improve code quality, but XO offers more flexibility and better support for modern JavaScript development workflows. JSLint, on the other hand, provides a more opinionated approach to writing JavaScript, which can be beneficial for teams looking for strict adherence to specific coding standards.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

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 .eslintrc 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.

JSX is supported by default, but you'll need eslint-config-xo-react for React specific linting. Vue components are not supported by default. 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
    --env             Environment preset  [Can be set multiple times]
    --global          Global variable  [Can be set multiple times]
    --ignore          Additional paths to ignore  [Can be set multiple times]
    --space           Use space indent instead of tabs  [Default: 2]
    --no-semicolon    Prevent use of semicolons
    --prettier        Conform to Prettier code style
    --node-version    Range of Node.js version to support
    --plugin          Include third-party plugins  [Can be set multiple times]
    --extend          Extend defaults with a custom config  [Can be set multiple times]
    --open            Open files with issues in your editor
    --quiet           Show only errors and no warnings
    --extension       Additional extension to lint [Can be set multiple times]
    --cwd=<dir>       Working directory for files
    --stdin           Validate/fix code from stdin
    --stdin-filename  Specify a filename for the --stdin option
    --print-config    Print the ESLint configuration for the given file

  Examples
    $ xo
    $ xo index.js
    $ xo *.js !foo.js
    $ xo --space
    $ xo --env=node --env=mocha
    $ xo --plugin=react
    $ xo --plugin=html --extension=html
    $ echo 'const x=true' | xo --stdin --fix
    $ xo --print-config=index.js

  Tips
    - Add XO to your project with `npm init xo`.
    - Put options in package.json 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 your package.json or create one.

Before/after

 {
 	"name": "awesome-package",
 	"scripts": {
-		"test": "ava",
+		"test": "xo && ava"
 	},
 	"devDependencies": {
-		"ava": "^3.0.0"
+		"ava": "^3.0.0",
+		"xo": "^0.41.0"
 	}
 }

Then just run $ npm test and XO will be run before your tests.

Config

You can configure XO options with one of the following files:

  1. As JSON in the xo property in package.json:
{
	"name": "awesome-package",
	"xo": {
		"space": true
	}
}
  1. As JSON in .xo-config or .xo-config.json:
{
	"space": true
}
  1. As a JavaScript module in .xo-config.js or xo.config.js:
module.exports = {
	space: true
};
  1. For ECMAScript module (ESM) packages with "type": "module", as a JavaScript module in .xo-config.cjs or xo.config.cjs:
module.exports = {
	space: true
};

Globals and rules can be configured inline in files.

envs

Type: string[]
Default: ['es2021', 'node']

Which environments your code is designed to run in. Each environment brings with it a certain set of predefined global variables.

globals

Type: string[]

Additional global variables your code accesses during execution.

ignores

Type: string[]

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

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".

rules

Type: object

Override any of the default rules. See the ESLint docs for more info on each rule.

Disable a rule in your XO config to turn it off globally in your project.

Example using package.json:

{
	"xo": {
		"rules": {
			"unicorn/no-array-for-each": "off"
		}
	}
}

You could also use .xo-config.json or one of the other config file formats supported by XO.

Please take a moment to consider if you really need to use this option.

semicolon

Type: boolean
Default: true (Semicolons required)

Set it to false to enforce no-semicolon style.

prettier

Type: boolean
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:

module.exports = {
	trailingComma: 'es5',
	singleQuote: false,
	bracketSpacing: true,
};

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

nodeVersion

Type: string | boolean
Default: Value of the engines.node key in the project package.json

Enable rules specific to the Node.js versions within the configured range.

If set to false, no rules specific to a Node.js version will be enabled.

plugins

Type: string[]

Include third-party plugins.

extends

Type: string | string[]

Use one or more shareable configs or plugin configs to override any of the default rules (like rules above).

extensions

Type: string[]

Allow more extensions to be linted besides .js, .jsx, .mjs, and .cjs as well as their TypeScript equivalents .ts, .tsx, .mts and .cts. Make sure they're supported by ESLint or an ESLint plugin.

settings

Type: object

Shared ESLint settings exposed to rules.

parser

Type: string

ESLint parser. For example, @babel/eslint-parser if you're using language features that ESLint doesn't yet support.

processor

Type: string

ESLint processor.

webpack

Type: boolean | object Default: false

Use eslint-import-resolver-webpack to resolve import search paths. This is enabled automatically if a webpack.config.js file is found.

Set this to a boolean to explicitly enable or disable the resolver.

Setting this to an object enables the resolver and passes the object as configuration. See the resolver readme along with the webpack documentation for more information.

TypeScript

XO will automatically lint TypeScript files (.ts, .mts, .cts, .d.ts 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.

GitHub Actions

XO uses a different formatter when running in a GitHub Actions workflow to be able to get inline annotations. XO also disables warnings here.

Note: For this to work, the setup-node action must be run before XO.

Config Overrides

XO makes it easy to override configs for specific files. The overrides property must be an array of override objects. Each override object must contain a files property which is a glob string, or an array of glob strings, relative to the config file. The remaining properties are identical to those described above, and will override the settings of the base config. If multiple override configs match the same file, each matching override is applied in the order it appears in the array. This means the last override in the array takes precedence over earlier ones. Consider the following example:

{
	"xo": {
		"semicolon": false,
		"space": 2,
		"overrides": [
			{
				"files": "test/*.js",
				"space": 3
			},
			{
				 "files": "test/foo.js",
				 "semicolon": true
			}
		]
	}
}
  • The base configuration is simply space: 2, semicolon: false. These settings are used for every file unless otherwise noted below.

  • For every file in test/*.js, the base config is used, but space is overridden with 3. The resulting config is:

{
	"semicolon": false,
	"space": 3
}
  • For test/foo.js, the base config is first applied, followed the first overrides config (its glob pattern also matches test/foo.js), finally the second override config is applied. The resulting config is:
{
	"semicolon": true,
	"space": 3
}

Tips

Using a parent's config

If you have a directory structure with nested package.json files and you want one of the child manifests to be skipped, you can do so by ommiting the xo property in the child's package.json. For example, when you have separate app and dev package.json files with electron-builder.

Monorepo

Put a package.json with your config at the root and omit the xo property in the package.json of your bundled packages.

Transpilation

If some files in your project are transpiled in order to support an older Node.js version, you can use the config overrides option to set a specific nodeVersion to target your sources files.

For example, if your project targets Node.js 8 but you want to use the latest JavaScript syntax as supported in Node.js 12:

  1. Set the engines.node property of your package.json to >=8
  2. Configure Babel to transpile your source files (in source directory in this example)
  3. Make sure to include the transpiled files in your published package with the files and main properties of your package.json
  4. Configure the XO overrides option to set nodeVersion to >=12 for your source files directory
{
	"engines": {
		"node": ">=12"
	},
	"scripts": {
		"build": "babel source --out-dir distribution"
	},
	"main": "distribution/index.js",
	"files": [
		"distribution/**/*.js"
	],
	"xo": {
		"overrides": [
			{
				"files": "source/**/*.js",
				"nodeVersion": ">=16"
			}
		]
	}
}

This way your package.json will contain the actual minimum Node.js version supported by your published code, but XO will lint your source code as if it targets Node.js 16.

Including files ignored by default

To include files that XO ignores by default, add them as negative globs in the ignores option:

{
	"xo": {
		"ignores": [
			"!vendor/**"
		]
	}
}

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&logoWidth=20)](https://github.com/xojs/xo)

Or customize the badge.

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

Team

Former

NPM DownloadsLast 30 Days