Skip to content

Guide

Welcome to the documentation for @ntnyq/eslint-config!

This guide will help you set up and configure ESLint with this opinionated preset.

Requirements

Before you start, make sure you have the following versions installed:

  • Node.js: ^20.19.0 || ^22.13.0 || >=24
  • ESLint: ^9.38.0

TIP

For Node.js v18 support, please use v4.

For Node.js versions below 20.19.0, please use v5.

Features

  • ✅ Designed to work alongside formatter e.g: Prettier or oxfmt
  • 🎯 Opinionated: single quote, no semi, trailing comma, etc
  • 🪄 Respect .gitignore via eslint-config-flat-gitignore
  • 📦 Out-of-the-box support for TypeScript, Vue, JSON, Markdown, YAML, TOML, SVG, Astro, Svelte, etc
  • 🛡️ Strict but provides useful rules to guard your codebase
  • 🔧 Custom ESLint commands for eslint-plugin-command
  • 🎪 ESLint flat config for ESLint v9.38.0+

Install

shell
npm i eslint typescript @ntnyq/eslint-config -D
shell
yarn add eslint typescript @ntnyq/eslint-config -D
shell
pnpm add eslint typescript @ntnyq/eslint-config -D
shell
bun add eslint typescript @ntnyq/eslint-config -D

Quick Start

Create an eslint.config.mjs file in your project root:

js
// @ts-check

import { defineESLintConfig } from '@ntnyq/eslint-config'

export default defineESLintConfig()

Add lint scripts to your package.json:

json
{
  "scripts": {
    "lint": "eslint",
    "lint:fix": "eslint --fix"
  }
}

That's it! Now you can run npm run lint to check your code.

Configuration Options

You can customize the preset by passing options to defineESLintConfig:

js
// @ts-check

import { defineESLintConfig } from '@ntnyq/eslint-config'

export default defineESLintConfig(
  // Options here
  {
    // Enable a config
    svgo: true,
    // Disable a config
    jsdoc: false,
    vue: {
      // Overrides built-in rules
      overrides: {
        'vue/slot-name-casing': 'off',
      },
    },
  },
  // Optional user configs here
  [
    {
      files: ['**/utils/*.ts'],
      rules: {
        'antfu/top-level-function': 'error',
      },
    },
  ],
)

Integration

🟢 Prettier
shell
npm i prettier @ntnyq/prettier-config -D
shell
yarn add prettier @ntnyq/prettier-config -D
shell
pnpm add prettier @ntnyq/prettier-config -D
shell
bun add prettier @ntnyq/prettier-config -D

Create prettier.config.mjs:

js
// @ts-check

import { defineConfig } from '@ntnyq/prettier-config'

export default defineConfig({
  // Custom options if needed
  printWidth: 100,
  trailingComma: 'none',
})

VS Code

Add these settings to your .vscode/settings.json:

json
{
  "eslint.enable": true,
  "prettier.enable": true,
  "editor.formatOnSave": true,
  "prettier.configPath": "./prettier.config.mjs",
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "never",
    "source.sortImports": "never"
  },
  "eslint.validate": [
    "vue",
    "yaml",
    "toml",
    "json",
    "jsonc",
    "json5",
    "markdown",
    "javascript",
    "typescript",
    "javascriptreact",
    "typescriptreact"
  ]
}

Git Hooks (husky + nano-staged)

Lint changed files only before committing:

shell
pnpm add husky nano-staged -D

Add to package.json:

json
{
  "scripts": {
    "prepare": "husky"
  },
  "nano-staged": {
    "*.{js,ts,cjs,mjs,jsx,tsx,vue,md,svg,yml,yaml,toml,json}": "eslint --fix",
    "*.{css,scss,html}": "prettier -uw"
  }
}

Create a Git hook:

shell
echo "nano-staged" > .husky/pre-commit
🔵 Oxfmt
shell
npm i oxfmt -D
shell
yarn add oxfmt -D
shell
pnpm add oxfmt -D
shell
bun add oxfmt -D

Create .oxfmtrc.json:

json
{
  "$schema": "./node_modules/oxfmt/configuration_schema.json",
  "arrowParens": "avoid",
  "bracketSameLine": false,
  "bracketSpacing": true,
  "embeddedLanguageFormatting": "auto",
  "endOfLine": "lf",
  "sortPackageJson": false,
  "htmlWhitespaceSensitivity": "css",
  "ignorePatterns": [
    "**/node_modules/**",
    "**/dist/**",
    "pnpm-lock.yaml",
    "**/*.min.*",
    "**/tests/fixtures/**"
  ],
  "insertFinalNewline": true,
  "jsxSingleQuote": true,
  "objectWrap": "preserve",
  "overrides": [
    {
      "files": ["**/*.{css,scss}"],
      "options": {
        "singleQuote": false
      }
    },
    {
      "files": ["**/*.html"],
      "options": {
        "singleAttributePerLine": false
      }
    }
  ],
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "semi": false,
  "singleAttributePerLine": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "useTabs": false,
  "vueIndentScriptAndStyle": false
}

VS Code

Add these settings to your .vscode/settings.json:

json
{
  "oxc.enable": true,
  "eslint.enable": true,
  "prettier.enable": true,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "oxc.oxc-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "never",
    "source.sortImports": "never"
  },
  "eslint.validate": [
    "vue",
    "yaml",
    "toml",
    "json",
    "jsonc",
    "json5",
    "markdown",
    "javascript",
    "typescript",
    "javascriptreact",
    "typescriptreact"
  ]
}

Git Hooks (husky + nano-staged)

Lint changed files only before committing:

shell
pnpm add husky nano-staged -D

Add to package.json:

json
{
  "scripts": {
    "prepare": "husky"
  },
  "nano-staged": {
    "*.{js,ts,cjs,mjs,jsx,tsx,vue,md,svg,yml,yaml,toml,json}": "eslint --fix",
    "*": "oxfmt --no-error-on-unmatched-pattern"
  }
}

Create a Git hook:

shell
echo "nano-staged" > .husky/pre-commit

View Rules

Check what rules are enabled using ESLint Config Inspector, powered by @eslint/config-inspector.

Next Steps