Advanced Usage
Advanced Usage
Type Aware Rules
Some of the strongest TypeScript lint rules require type information — they need to resolve what a value actually is at runtime, not just what its local syntax looks like. Opt into type-aware linting by pointing at your tsconfig.json:
import pleaseai from '@pleaseai/eslint-config'
export default pleaseai({
typescript: {
tsconfigPath: 'tsconfig.json',
},
})
Config Composer
pleaseai() returns a FlatConfigComposer, so you can fluently override, prepend, remove, or rename named config blocks when the plain options object isn't granular enough:
import pleaseai from '@pleaseai/eslint-config'
export default pleaseai()
.prepend(
// flat configs before the main PleaseAI config
)
.override('antfu/stylistic/rules', {
rules: {
'style/generator-star-spacing': ['error', { after: true, before: false }],
},
})
.renamePlugins({
'old-prefix': 'new-prefix',
})
.remove('antfu/stylistic')
Reach for this API when:
- You want to remove a named config block entirely
- You need to rename a plugin prefix without writing a custom config
- You want to override rules inside a specific named block (more surgical than the top-level
overrides)
command Codemods
@pleaseai/eslint-config ships eslint-plugin-command — an on-demand micro-codemod system triggered by triple-slash comments. It's not a typical lint rule; you explicitly opt in per-site.
Built-in triggers include:
/// to-function— arrow function →functiondeclaration/// to-arrow—functiondeclaration → arrow function/// to-for-each—forloop →.forEach()/// to-for-of—.forEach()→for-of/// keep-sorted— sort the next object/array/interface
See the plugin docs for the full catalogue.
Usage — place the trigger one line above the code:
/// to-function
const greet = async (name: string): Promise<void> => {
console.log(`Hello, ${name}`)
}
After eslint --fix:
async function greet(name: string): Promise<void> {
console.log(`Hello, ${name}`)
}
The trigger comment is one-off — it's removed along with the transformation.
Plugins Renaming
@pleaseai/eslint-config inherits @antfu/eslint-config's plugin renaming for a shorter, 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 |
So when you override a rule, use the new prefix:
import pleaseai from '@pleaseai/eslint-config'
export default pleaseai({
rules: {
'ts/consistent-type-definitions': ['error', 'interface'],
'style/max-statements-per-line': ['error', { max: 2 }],
},
})
View Enabled Rules
Use @eslint/config-inspector to visualise the fully-resolved config in a browser — every enabled rule, every plugin, every file glob:
npx @eslint/config-inspector
It opens a local server showing the flat config graph. Indispensable when you're debugging "why is this rule firing" or "which preset added this".
Re-exports
Every export from @antfu/eslint-config is re-exported, so you can import fine-grained configs directly when you want to compose them by hand instead of using the pleaseai() factory:
import { combine, javascript, typescript, vue } from '@pleaseai/eslint-config'
export default combine(
javascript(),
typescript(),
vue(),
)
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.
Breaking (major bump)
- 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
Non-breaking (minor/patch)
- Enabling or disabling individual rules (even if stricter)
- Changing rule options
- Dependency version bumps
If a rule tightening breaks your build, pin to the previous minor version and open an issue so we can discuss the trade-off.