npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pleaseai/eslint-config

v0.0.4

Published

ESLint config for PleaseAI projects

Readme

@pleaseai/eslint-config

English | 한국어

npm

PleaseAI's shared ESLint config, built on top of @antfu/eslint-config.

PleaseAI Defaults

This config wraps @antfu/eslint-config with the following defaults:

| Option | Value | |--------|-------| | Indent | 2 spaces | | Quotes | Single | | Semicolons | No | | TypeScript | Enabled | | Gitignore | Enabled | | 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 |

Additionally, test/prefer-lowercase-title is disabled.

Usage

Install

bun add -D @pleaseai/eslint-config eslint

Configure

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

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai()

Add scripts to package.json

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

Customization

The pleaseai() function accepts the same options as antfu(). All @antfu/eslint-config options are supported.

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',
  ],
})

You can also pass additional flat configs as extra arguments:

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai(
  {
    // PleaseAI + antfu options
    typescript: true,
  },
  // Additional ESLint flat configs
  {
    files: ['**/*.ts'],
    rules: {
      'ts/consistent-type-definitions': ['error', 'interface'],
    },
  },
)

Config Composer

The factory function pleaseai() returns a FlatConfigComposer object from eslint-flat-config-utils, so you can chain methods to compose the config even more flexibly:

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai()
  .prepend(
    // some flat configs before the main config
  )
  // override any named config block
  .override(
    'antfu/stylistic/rules',
    {
      rules: {
        'style/generator-star-spacing': ['error', { after: true, before: false }],
      },
    },
  )
  // rename plugin prefixes
  .renamePlugins({
    'old-prefix': 'new-prefix',
    // ...
  })
  // remove a named config block entirely
  .remove('antfu/stylistic')

This is the composable escape-hatch when the plain pleaseai({ ... }) options are not granular enough.

Rules Overrides

Use the overrides option in each integration:

import pleaseai from '@pleaseai/eslint-config'

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

Type Aware Rules

Enable type aware rules by passing tsconfigPath:

import pleaseai from '@pleaseai/eslint-config'

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

Optional Configs

React

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  react: true,
})
bun add -D @eslint-react/eslint-plugin eslint-plugin-react-refresh

Next.js

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  nextjs: true,
})
bun add -D @next/eslint-plugin-next

Vue

Vue support is auto-detected. You can also explicitly enable it:

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  vue: true,
})

Svelte

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  svelte: true,
})
bun add -D eslint-plugin-svelte

Astro

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  astro: true,
})
bun add -D eslint-plugin-astro

Solid

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  solid: true,
})
bun add -D eslint-plugin-solid

UnoCSS

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  unocss: true,
})
bun add -D @unocss/eslint-plugin

Angular

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  angular: true,
})
bun add -D @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/template-parser

Optional Rules — command

@antfu/eslint-config ships with eslint-plugin-command, which @pleaseai/eslint-config inherits. It is not a typical lint rule — it's an on-demand micro-codemod that triggers on specific triple-slash comments.

A few built-in triggers:

  • /// to-function — converts an arrow function to a function declaration
  • /// to-arrow — converts a function declaration to an arrow function
  • /// to-for-each — converts a for-loop to .forEach()
  • /// to-for-of — converts a .forEach() to a for-of
  • /// keep-sorted — sorts the next object/array/interface
  • …see the plugin docs for the full list

Place the trigger one line above the code you want to transform:

/// to-function
const foo = async (msg: string): Promise<void> => {
  console.log(msg)
}

On the next eslint --fix (or auto-fix-on-save) it becomes:

async function foo(msg: string): Promise<void> {
  console.log(msg)
}

The trigger comment is one-off — it's removed along with the transformation.

Formatters

Use external formatters for files that ESLint cannot handle yet (.css, .html, etc):

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  formatters: {
    css: true,
    html: true,
    markdown: 'prettier',
  },
})
bun add -D eslint-plugin-format

Package JSON Linting

This package also exports eslint-plugin-package-json configs:

import { recommended, stylistic } from '@pleaseai/eslint-config/package-json'
  • recommendedeslint-plugin-package-json recommended-publishable config
  • stylisticeslint-plugin-package-json stylistic config

IDE Support (auto fix on save)

VS Code

Install VS Code ESLint extension and add the following to .vscode/settings.json:

{
  // Disable the default formatter, use eslint instead
  "prettier.enable": false,
  "editor.formatOnSave": false,

  // Auto fix
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "never"
  },

  // Silent the stylistic rules in your IDE, but still auto fix them
  "eslint.rules.customizations": [
    { "rule": "style/*", "severity": "off", "fixable": true },
    { "rule": "format/*", "severity": "off", "fixable": true },
    { "rule": "*-indent", "severity": "off", "fixable": true },
    { "rule": "*-spacing", "severity": "off", "fixable": true },
    { "rule": "*-spaces", "severity": "off", "fixable": true },
    { "rule": "*-order", "severity": "off", "fixable": true },
    { "rule": "*-dangle", "severity": "off", "fixable": true },
    { "rule": "*-newline", "severity": "off", "fixable": true },
    { "rule": "*quotes", "severity": "off", "fixable": true },
    { "rule": "*semi", "severity": "off", "fixable": true }
  ],

  // Enable eslint for all supported languages
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue",
    "html",
    "markdown",
    "json",
    "jsonc",
    "yaml",
    "toml",
    "xml",
    "gql",
    "graphql",
    "astro",
    "svelte",
    "css",
    "less",
    "scss",
    "pcss",
    "postcss"
  ]
}

Neovim

A few ways to get format-on-save in Neovim:

  • nvim-lspconfig exposes an EslintFixAll command. Create an autocmd that runs it on BufWritePre:

    lspconfig.eslint.setup({
      on_attach = function(client, bufnr)
        vim.api.nvim_create_autocmd('BufWritePre', {
          buffer = bufnr,
          command = 'EslintFixAll',
        })
      end,
    })
  • conform.nvim

  • none-ls.nvim

  • nvim-lint

Editor Specific Disables

When ESLint runs inside a code editor, a handful of rules are disabled for auto-fix so the editor doesn't aggressively rewrite code you're still typing:

Since @antfu/eslint-config v3.16.0 these rules are not disabled — they're made non-fixable in editor mode. They still report, just without a quick-fix action.

Motivation: an unused import you just pasted shouldn't vanish the moment your editor auto-saves. The rules still apply when you run eslint in the terminal or through Lint Staged. If you prefer the uniform behaviour across editor and CLI, opt out:

import pleaseai from '@pleaseai/eslint-config'

export default pleaseai({
  isInEditor: false,
})

Lint Staged

{
  "simple-git-hooks": {
    "pre-commit": "bun lint-staged"
  },
  "lint-staged": {
    "*": "eslint --fix"
  }
}
bun add -D lint-staged simple-git-hooks
npx simple-git-hooks

View Enabled Rules

Use @eslint/config-inspector to visualize what rules are enabled:

npx @eslint/config-inspector

Plugins Renaming

This config inherits @antfu/eslint-config's plugin renaming for a consistent DX:

| New Prefix | Original Prefix | Source Plugin | |------------|-----------------|---------------| | import/* | import-lite/* | eslint-plugin-import-lite | | node/* | n/* | eslint-plugin-n | | yaml/* | yml/* | eslint-plugin-yml | | ts/* | @typescript-eslint/* | @typescript-eslint/eslint-plugin | | style/* | @stylistic/* | @stylistic/eslint-plugin | | test/* | vitest/* | @vitest/eslint-plugin |

Versioning Policy

@pleaseai/eslint-config follows Semantic Versioning, but because it's an opinionated style preset with many moving parts, rule changes are not treated as breaking changes. The tables below match the policy inherited from @antfu/eslint-config.

Considered breaking

  • Node.js version requirement changes
  • Large refactors that may break downstream configs
  • Major plugin upgrades that may break existing rules
  • Changes that likely affect most codebases

Considered non-breaking

  • Enabling/disabling individual rules or plugins (even if stricter)
  • Changing rule options
  • Dependency version bumps

If a rule tightening breaks your lint, pin to a previous minor version and open an issue so we can discuss the trade-off.

FAQ

Prettier?

This config uses ESLint for both linting and formatting, so Prettier is not needed. See Why I don't use Prettier by Anthony Fu.

If you need to format files that ESLint cannot handle yet (.css, .html, etc.), use the formatters option instead.

How to format CSS?

You can opt-in to the formatters feature to format your CSS. Note that it only does formatting, not linting. If you want proper linting support, give stylelint a try.

Top-level function style?

PleaseAI re-enables antfu/top-level-function on top of lessOpinionated: true, 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 with this choice, override it:

import pleaseai from '@pleaseai/eslint-config'

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

Curly braces style?

PleaseAI defaults to lessOpinionated: true, which enforces curly: ['error', 'all'] — always require braces around control flow bodies:

// PleaseAI style — always requires braces
function example() {
  if (foo) {
    return true
  }
}

The antfu default (lessOpinionated: false) allows brace-less single-line if with a newline, but PleaseAI enforces curly: ['error', 'all'].

Note: antfu/top-level-function is re-enabled, so top-level function declarations are still preferred over arrow functions.

Re-exports

All exports from @antfu/eslint-config are re-exported, so you can import fine-grained configs directly:

import { combine, javascript, typescript, vue } from '@pleaseai/eslint-config'

License

MIT