Skip to content

ESLint Config

Opinionated ESLint flat config for PleaseAI projects — built on @antfu/eslint-config.

Updated View as Markdown

@pleaseai/eslint-config is an opinionated ESLint flat config built on top of @antfu/eslint-config. It gives you a single pleaseai() function that wires up linting and formatting for JS/TS/JSX/Vue/JSON/YAML/Markdown out of the box — no Prettier required.

Features

Installation

Usage

Create eslint.config.ts (or eslint.config.mjs) in your project root:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai()

That’s it. ESLint will pick it up automatically on the next run.

With Options

pleaseai() accepts the same options as @antfu/eslint-config:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  // Override PleaseAI defaults
  stylistic: {
    indent: 4,
  },

  // Enable framework support
  vue: true,
  react: true,

  // Add ignores
  ignores: [
    '**/fixtures',
  ],
})

See Framework Integrations for the full list of framework flags and their peer dependencies.

With Additional Configs

Pass additional flat config items as rest arguments — they’re merged after the PleaseAI preset:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai(
  {
    typescript: true,
  },
  {
    files: ['**/*.ts'],
    rules: {
      'no-console': 'warn',
    },
  },
)

Rules Overrides

Every framework integration accepts an overrides object so you can tune rules without replacing the whole preset:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  vue: {
    overrides: {
      'vue/operator-linebreak': ['error', 'before'],
    },
  },
  typescript: {
    overrides: {
      'ts/consistent-type-definitions': ['error', 'interface'],
    },
  },
})

For overrides that don’t fit a specific integration, pass a second argument with a rules object as shown in With Additional Configs.

NPM Scripts

Add the lint commands to your package.json:

package.jsonjson
{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  }
}

Run npm run lint to check, or npm run lint:fix to auto-fix.

PleaseAI Defaults

This config wraps @antfu/eslint-config with these PleaseAI-specific defaults:

Option Value Note
stylistic.indent 2 Two-space indent
stylistic.quotes single Single quotes
stylistic.semi false No trailing semicolons
typescript true Enabled out of the box
gitignore true Ignores anything in .gitignore
lessOpinionated true Disables antfu/if-newline and antfu/curly, enables curly: ['error', 'all']
antfu/top-level-function Re-enabled Prefer function declarations at top level
test/prefer-lowercase-title Disabled Test titles can start with any case

The lessOpinionated: true + curly: ['error', 'all'] combination is the key PleaseAI divergence from antfu’s defaults: control-flow statements must always use braces, but antfu’s top-level-function preference is still honoured.

Formatters

ESLint can’t natively format .css, .html, .xml, or Markdown frontmatter. Opt in to the formatters feature to delegate those files to eslint-plugin-format (which wraps Prettier / dprint) while keeping everything else on pure ESLint:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  formatters: {
    css: true,
    html: true,
    markdown: 'prettier',
  },
})

Type Aware Rules

The strongest TypeScript rules require type information. Opt in by pointing at your tsconfig.json:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  typescript: {
    tsconfigPath: 'tsconfig.json',
  },
})

Read more in Advanced Usage → Type Aware Rules.

Next Steps

Advanced Usage

Config Composer, command codemods, plugin renaming, versioning policy.

Editor & CI

VS Code, Neovim, editor-specific disables, and lint-staged.

FAQ

Prettier?

This config uses ESLint for both linting and formatting, so Prettier isn’t needed. See Why I don’t use Prettier by Anthony Fu for the reasoning.

If you need to format files ESLint can’t handle yet (.css, .html, etc.), use the formatters option — it wraps Prettier/dprint under the hood without adding a separate tool to your workflow.

How do I format CSS?

Opt in to the formatters feature. It formats but does not lint — for proper CSS linting pair it with Stylelint.

Curly braces style?

PleaseAI enforces curly: ['error', 'all'] — always wrap control-flow bodies in braces:

// ✓ required
function example() {
  if (foo) {
    return true
  }
}

// ✗ rejected
function example() {
  if (foo) return true
}

This diverges from antfu’s default (which allows brace-less single-line if). We made this choice because brace-less bodies interact badly with our other rules like style/max-statements-per-line — mixing them produces hard-to-read one-liners.

Top-level function style?

PleaseAI re-enables antfu/top-level-function, so top-level functions should use a function declaration rather than an arrow assigned to a const:

// ✓ preferred
export function greet(name: string) {
  return `Hello, ${name}`
}

// ✗ flagged
export const greet = (name: string) => `Hello, ${name}`

Arrow functions are still fine inside function bodies, as callbacks, or for inline JSX handlers — the rule only targets top-level declarations. If you disagree, override it:

eslint.config.tsts
import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  rules: {
    'antfu/top-level-function': 'off',
  },
})
Navigation

Type to search…

↑↓ navigate↵ selectEsc close