
Shared Tooling Eslint Prettier
- 8 installs
- 19 repo stars
- Updated July 19, 2026
- agents-inc/skills
shared-tooling-eslint-prettier is a Claude Code skill that teaches ESLint 9/10 flat config and Prettier setup with typed linting and shared configs.
About
A Claude Code skill for configuring ESLint 9/10 flat config and Prettier. It covers defineConfig() and globalIgnores(), typescript-eslint v8+ with projectService, Prettier shared config, eslint-config-prettier to avoid conflicts, eslint-plugin-only-warn for developer experience, and migrating from legacy .eslintrc. A developer uses it when setting up or modernizing linting and formatting on a TypeScript project.
- ESLint 9/10 flat config with defineConfig() and globalIgnores()
- typescript-eslint v8+ projectService for typed linting
- Prettier + eslint-config-prettier with no rule conflicts
Shared Tooling Eslint Prettier by the numbers
- 8 all-time installs (skills.sh)
- Ranked #839 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Data as of Aug 1, 2026 (Skillselion catalog sync)
shared-tooling-eslint-prettier capabilities & compatibility
- Capabilities
- linting · code formatting · typed linting · config migration
- Use cases
- code review
- IDEs
- vscode · cursor ide · jetbrains
- Pricing
- Free
What shared-tooling-eslint-prettier says it does
ESLint 9+ flat config with `defineConfig()` and `globalIgnores()`. typescript-eslint v8+ with `projectService: true`.
npx skills add https://github.com/agents-inc/skills --skill shared-tooling-eslint-prettierAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 8 |
|---|---|
| repo stars | ★ 19 |
| Last updated | July 19, 2026 |
| Repository | agents-inc/skills ↗ |
What it does
Set up ESLint 9/10 flat config with Prettier and typed linting on a TypeScript project.
Who is it for?
TypeScript projects adopting ESLint 9/10 flat config with Prettier and typed linting via projectService.
Skip if: Runtime application code, CI/CD pipeline config, git hooks/lint-staged, or tsconfig compiler setup.
When should I use this skill?
Configuring ESLint 9 flat config, Prettier formatting, shared linting configs, or migrating from legacy .eslintrc.
What you get
A modern flat-config ESLint plus Prettier setup with typed linting and no conflicting formatting rules.
- eslint.config.ts flat config
- prettier config
- shared config package (optional)
By the numbers
- ESLint 10 released February 2026 (removes .eslintrc)
- typescript-eslint v8+ with projectService
Files
ESLint & Prettier
Quick Guide: ESLint 9+ flat config withdefineConfig()andglobalIgnores(). typescript-eslint v8+ withprojectService: true. Prettier shared config with consistent formatting. eslint-config-prettier to disable conflicting rules. eslint-plugin-only-warn for better DX.
>
WARNING: ESLint 10 was released February 2026 and completely removes .eslintrc support. Migrate to flat config now.
---
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST use ESLint 9+ flat config with `defineConfig()` from `eslint/config` - NOT legacy .eslintrc)
(You MUST use `globalIgnores()` for explicit global ignore patterns - NOT bare `ignores` property)
(You MUST use typescript-eslint v8+ with `projectService: true` for typed linting)
(You MUST include eslint-plugin-only-warn to convert errors to warnings for better DX)
(You MUST use eslint-config-prettier to disable formatting rules that conflict with Prettier)
</critical_requirements>
---
Auto-detection: ESLint 9 flat config, defineConfig, globalIgnores, eslint.config.ts, Prettier config, prettier.config.mjs, eslint-config-prettier, eslint-plugin-only-warn, typescript-eslint projectService, .eslintrc migration
When to use:
- Setting up ESLint 9/10 flat config (standalone or shared)
- Configuring Prettier with shared config
- Migrating from legacy .eslintrc to flat config
- Integrating ESLint and Prettier (eslint-config-prettier)
- Configuring typescript-eslint v8+ with projectService
- Setting up custom ESLint rules (named exports, import restrictions, type imports)
When NOT to use:
- Runtime code (this is build-time tooling only)
- CI/CD pipeline configuration
- Git hooks or lint-staged setup
- TypeScript compiler configuration (tsconfig)
- Bundler configuration
Detailed Resources:
- examples/core.md - Essential flat config + Prettier setup
- examples/eslint.md - Advanced ESLint patterns (shared configs, custom rules, ESLint 10 migration)
- examples/prettier.md - Advanced Prettier patterns (TS config, experimental options, ignore files)
- reference.md - Version reference and official documentation links
---
<philosophy>
Philosophy
Linting and formatting should be fast, consistent, and non-blocking. Developers should not fight with tools - tools should help catch issues early while staying out of the way during development.
Core principles:
1. Warnings, not errors - Use only-warn to convert lint errors to warnings so developers can iterate without being blocked 2. Single source of truth - Shared configs prevent drift between packages and team members 3. Automate formatting - Prettier handles all formatting decisions; ESLint handles code quality only 4. No conflicts - eslint-config-prettier ensures ESLint and Prettier never disagree
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: ESLint 9+ Flat Config with defineConfig()
ESLint 9+ uses flat config. The defineConfig() helper from eslint/config provides type safety and automatic array flattening. globalIgnores() explicitly marks global ignore patterns.
// eslint.config.ts — the essential flat config
import js from "@eslint/js";
import { defineConfig, globalIgnores } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import * as onlyWarnPlugin from "eslint-plugin-only-warn";
export default defineConfig(
globalIgnores(["dist/**", "generated/**", "node_modules/**"]),
js.configs.recommended,
eslintConfigPrettier,
tseslint.configs.recommended,
{ plugins: { "only-warn": onlyWarnPlugin } }, // must be last
);Key points: defineConfig() auto-flattens arrays (no spread operators needed), globalIgnores() prevents ambiguous behavior of bare ignores, only-warn converts all preceding errors to warnings, eslint-config-prettier disables formatting rules that conflict with Prettier.
See examples/core.md for the complete standalone and shared config patterns.
---
Pattern 2: typescript-eslint v8+ with projectService
The projectService feature (stable since v8) auto-discovers the nearest tsconfig.json for each file, replacing the fragile manual project path.
parserOptions: {
projectService: true,
allowDefaultProject: ["*.config.ts", "*.config.mjs"],
},Key points: Eliminates need for tsconfig.eslint.json files, faster than manual project configuration, allowDefaultProject handles config files not in tsconfig.
See examples/core.md for full typescript-eslint configuration.
---
Pattern 3: Shared Config Pattern (Monorepos/Teams)
For teams or monorepos, extract linting config into a shared package to prevent drift.
// packages/eslint-config/base.ts — shared config
export const baseConfig = defineConfig(
globalIgnores(["dist/**", "generated/**"]),
js.configs.recommended,
eslintConfigPrettier,
tseslint.configs.recommended,
{ plugins: { "only-warn": onlyWarnPlugin } },
);
// apps/my-app/eslint.config.ts — consuming shared config
export default defineConfig(baseConfig, customRules, {
rules: { "no-console": "warn" },
});Key points: defineConfig() auto-flattens so no spread operators needed, single source of truth prevents config drift, TypeScript config file for type checking.
See examples/eslint.md for shared config and custom rules patterns.
---
Pattern 4: Prettier Shared Config
Prettier config should be consistent across all packages. Use a shared config for teams.
// prettier.config.mjs
const config = {
printWidth: 100,
semi: true,
singleQuote: false,
bracketSpacing: true,
arrowParens: "always",
endOfLine: "lf",
bracketSameLine: false,
// trailingComma: "all" is the default in Prettier 3.0+
};
export default config;Key points: trailingComma: "all" is the default in v3.0+ (don't set it explicitly), bracketSameLine replaces deprecated jsxBracketSameLine, explicit endOfLine: "lf" prevents cross-platform issues.
See examples/prettier.md for TypeScript config files, experimental options, and ignore patterns.
---
Pattern 5: Custom ESLint Rules
Common custom rules for enforcing project conventions — named exports, consistent type imports, unused variable detection, and import boundary enforcement:
export const customRules = {
rules: {
"import/no-default-export": "warn",
"@typescript-eslint/consistent-type-imports": [
"warn",
{ prefer: "type-imports" },
],
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
},
};See examples/eslint.md for the full custom rules pattern including import boundary restrictions.
---
Pattern 6: Using extends Property (ESLint 9.15+)
The extends property in flat config objects simplifies plugin composition — standardizes config merging regardless of plugin format (object, array, or string):
export default defineConfig({
files: ["**/*.ts", "**/*.tsx"],
extends: [
"eslint/recommended",
tseslint.configs.recommended,
// Add your framework plugin's flat config here
],
rules: { "no-console": "warn" },
});See examples/core.md for the full extends pattern.
</patterns>
---
<decision_framework>
Decision Framework
ESLint + Prettier vs Alternatives
Need linting and formatting?
├─ Speed is critical bottleneck (1000+ files)?
│ └─ YES → Consider a Rust-based unified linter/formatter (not this skill's scope)
└─ Need mature plugin ecosystem?
└─ YES → ESLint 9/10 + Prettier ✓ESLint + Prettier strengths: Mature ecosystem, extensive plugin support, framework-specific plugins
ESLint 9 vs ESLint 10
Which ESLint version?
├─ New project?
│ └─ ESLint 10 (latest, cleanest API)
├─ Existing project with flat config?
│ └─ ESLint 10 (straightforward upgrade)
├─ Existing project with .eslintrc?
│ ├─ Can invest time to migrate?
│ │ └─ YES → Migrate to flat config, then ESLint 10
│ └─ NO → ESLint 9.x (still supported, but plan migration)
└─ Node.js < 20.19.0?
└─ ESLint 9.x (ESLint 10 requires 20.19.0+)Shared Config vs Local Config
Setting up linting/formatting?
├─ Monorepo with multiple packages?
│ └─ YES → Shared config ✓
├─ Team project (2+ developers)?
│ └─ YES → Shared config (consistency matters)
└─ Single package / solo project?
└─ YES → Local config is finePrettier Config File Format
What Prettier config format to use?
├─ Need type checking in config?
│ ├─ Node.js 22.6.0+? → prettier.config.ts
│ └─ NO → Use .mjs with JSDoc types
├─ ESM project? → prettier.config.mjs
└─ CommonJS project? → prettier.config.cjs</decision_framework>
---
<red_flags>
RED FLAGS
High Priority Issues:
- ❌ Using legacy .eslintrc format instead of ESLint 9+ flat config (BROKEN in ESLint 10)
- ❌ Using bare
ignoresproperty instead ofglobalIgnores()helper (ambiguous behavior — acts as global ignores when alone, but as local excludes when paired with other properties) - ❌ Missing eslint-plugin-only-warn (errors block developers during development)
- ❌ Missing eslint-config-prettier (ESLint and Prettier rules conflict, creating endless fix cycles)
Medium Priority Issues:
- ⚠️ Using manual
projectoption instead ofprojectService: truein typescript-eslint (fragile in monorepos, slower) - ⚠️ Using deprecated
jsxBracketSameLineoption in Prettier (renamed tobracketSameLinein Prettier 2.4) - ⚠️ Explicitly setting
trailingComma: "all"in Prettier 3.0+ (it is already the default) - ⚠️ Using
tseslint.config()wrapper (planned for deprecation in favor of ESLint's nativedefineConfig()) - ⚠️ Hardcoded config values in each package instead of shared config
Gotchas & Edge Cases:
- only-warn plugin must be loaded AFTER other plugins to convert their errors to warnings
defineConfig()auto-flattens arrays — never use spread operators with itprojectServicerequires typescript-eslint v8+ (wasEXPERIMENTAL_useProjectServicein v6-v7)- ESLint 10 requires Node.js
^20.19.0 || ^22.13.0 || >=24(v21.x and v23.x explicitly unsupported) - ESLint 10 config lookup starts from linted file directory (not cwd) — enables monorepo multi-config
- Prettier TypeScript config files (
.prettierrc.ts) require Node.js 22.6.0+; before Node v24.3.0 run with--experimental-strip-types - Prettier 3.0+ APIs are async — plugins using sync APIs need migration (use
@prettier/syncfor sync wrappers) - ESLint 9.15+:
eslint.config.tsTypeScript config files andextendsproperty supported natively - ESLint 9.34+: Multithreaded linting available via
--concurrencyflag (30-300% performance boost on large projects) - ESLint 10:
/* eslint-env */comments now trigger errors; deprecatedLintermethods removed
</red_flags>
---
<critical_reminders>
CRITICAL REMINDERS
All code must follow project conventions in CLAUDE.md
(You MUST use ESLint 9+ flat config with `defineConfig()` from `eslint/config` - NOT legacy .eslintrc)
(You MUST use `globalIgnores()` for explicit global ignore patterns - NOT bare `ignores` property)
(You MUST use typescript-eslint v8+ with `projectService: true` for typed linting)
(You MUST include eslint-plugin-only-warn to convert errors to warnings for better DX)
(You MUST use eslint-config-prettier to disable formatting rules that conflict with Prettier)
Failure to follow these rules will cause inconsistent tooling, conflicting formatting rules, and blocked developers.
WARNING: ESLint 10 (February 2026) completely removes .eslintrc support. Plan migration now.
</critical_reminders>
ESLint & Prettier - Core Examples
Essential patterns for ESLint 9+ flat config with Prettier integration. See eslint.md for shared configs, custom rules, and ESLint 10 migration. See prettier.md for TypeScript config files and experimental options.
---
Pattern 1: Standalone Flat Config
The minimal production-ready ESLint config combining flat config, typescript-eslint, Prettier, and only-warn:
// eslint.config.ts
import js from "@eslint/js";
import { defineConfig, globalIgnores } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import * as onlyWarnPlugin from "eslint-plugin-only-warn";
export default defineConfig(
// Global ignores using the helper function
globalIgnores(["dist/**", "generated/**", "node_modules/**"]),
js.configs.recommended,
eslintConfigPrettier,
// typescript-eslint recommended rules
tseslint.configs.recommended,
// Convert all errors to warnings for better DX (must be last)
{
plugins: {
"only-warn": onlyWarnPlugin,
},
},
);Why good: defineConfig() provides type safety and auto-flattens nested arrays, globalIgnores() explicitly marks global ignores (clearer intent than bare ignores), only-warn plugin loaded last converts all preceding errors to warnings, eslint-config-prettier disables formatting rules that conflict with Prettier
// BAD: Legacy .eslintrc format (BROKEN in ESLint 10)
// .eslintrc.json (DON'T USE THIS)
{
"extends": ["eslint:recommended", "prettier"],
"plugins": ["@typescript-eslint"],
"rules": {
"no-unused-vars": "error"
},
"ignorePatterns": ["dist/"]
}Why bad: Legacy .eslintrc is deprecated in ESLint 9 and completely removed in ESLint 10 (February 2026), error severity blocks developers during development, no only-warn plugin
---
Pattern 2: typescript-eslint v8+ with projectService
// eslint.config.ts — adding typed linting
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig(tseslint.configs.recommended, {
languageOptions: {
parser: tseslint.parser,
parserOptions: {
// projectService replaces the old project/parserOptions pattern
projectService: true,
// Allows linting files not in tsconfig (like config files)
allowDefaultProject: ["*.config.ts", "*.config.mjs"],
},
},
});Why good: projectService auto-discovers nearest tsconfig.json for each file, allowDefaultProject lints config files without adding them to tsconfig, faster than manual project configuration, eliminates need for tsconfig.eslint.json files
// BAD: Manual project option (old approach)
parserOptions: {
project: "./tsconfig.json", // Fragile path, no auto-discovery
}Why bad: Manual project path is fragile in monorepos, requires tsconfig.eslint.json for config files, slower than projectService
---
Pattern 3: Using extends Property (ESLint 9.15+)
The extends property simplifies plugin composition by standardizing config merging regardless of plugin format:
// eslint.config.ts
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig({
files: ["**/*.ts", "**/*.tsx"],
extends: [
// String references for standard configs
"eslint/recommended",
// Plugin configs (various formats supported)
tseslint.configs.recommended,
// Add your framework plugin's flat config here
],
rules: {
// Override specific rules
"no-console": "warn",
},
});Why good: Standardizes config merging regardless of plugin format (object, array, or string), cleaner than spreading arrays manually, conditionally applies configs based on file patterns. Add your framework-specific plugins via extends as needed.
---
Pattern 4: Prettier Standard Config
// prettier.config.mjs (standalone project)
// OR packages/prettier-config/prettier.config.mjs (shared config)
const config = {
printWidth: 100,
useTabs: false,
tabWidth: 2,
semi: true,
singleQuote: false,
// trailingComma: "all" is the default in Prettier 3.0+
bracketSpacing: true,
arrowParens: "always",
endOfLine: "lf",
// bracketSameLine replaces deprecated jsxBracketSameLine (Prettier 2.4+)
bracketSameLine: false,
};
export default config;Why good: Single source of truth prevents formatting inconsistencies, explicit endOfLine: "lf" prevents cross-platform line ending issues, double quotes match JSON format reducing escaping in JSX
---
Pattern 5: eslint-config-prettier Integration
eslint-config-prettier disables all ESLint rules that conflict with Prettier formatting. It must be included after other configs:
// eslint.config.ts — correct integration
import { defineConfig } from "eslint/config";
import eslintConfigPrettier from "eslint-config-prettier";
import tseslint from "typescript-eslint";
export default defineConfig(
tseslint.configs.recommended,
// eslint-config-prettier AFTER other configs to disable conflicting rules
eslintConfigPrettier,
);Why good: Prevents ESLint from reporting formatting issues that Prettier will handle, eliminates "fix one, break the other" cycles
// BAD: Missing eslint-config-prettier
export default defineConfig(
tseslint.configs.recommended,
// No eslint-config-prettier - ESLint and Prettier will fight over formatting
);Why bad: ESLint rules like indent, quotes, semi will conflict with Prettier's formatting, creating an endless cycle of conflicting auto-fixes
ESLint - Advanced Examples
Shared configs, custom rules, and ESLint 10 migration. See core.md for essential flat config setup.
Prerequisites: Understand Pattern 1 (Standalone Flat Config) and Pattern 2 (projectService) from core.md first.
---
Pattern 6: Shared Config Package
For teams or monorepos, extract linting config into a shared package:
// packages/eslint-config/base.ts
import js from "@eslint/js";
import { defineConfig, globalIgnores } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import * as onlyWarnPlugin from "eslint-plugin-only-warn";
export const baseConfig = defineConfig(
globalIgnores(["dist/**", "generated/**", "build/**"]),
js.configs.recommended,
eslintConfigPrettier,
tseslint.configs.recommended,
// Convert all errors to warnings for better DX
{
plugins: {
"only-warn": onlyWarnPlugin,
},
},
);Why good: Single source of truth prevents config drift, defineConfig() provides type safety, explicit globalIgnores() for clarity
---
Pattern 7: Consuming Shared Config
// apps/my-app/eslint.config.ts
import { defineConfig } from "eslint/config";
import { baseConfig } from "@company/eslint-config";
import { customRules } from "@company/eslint-config/custom-rules";
export default defineConfig(baseConfig, customRules, {
// App-specific overrides
rules: {
"no-console": "warn",
},
});Why good: No spread operators needed with defineConfig() (auto-flattens), clean composition of shared configs
// BAD: Manual spreading (old pattern)
export default [
...baseConfig,
customRules,
{ rules: { "no-console": "warn" } },
];Why bad: Spread operator required for array configs, no type safety, easy to make mistakes with array composition
---
Pattern 8: Custom ESLint Rules
Common custom rules for enforcing project conventions:
// packages/eslint-config/custom-rules.js
export const customRules = {
rules: {
// Enforce named exports for better tree-shaking
"import/no-default-export": "warn",
// Prevent importing from internal package paths
"no-restricted-imports": [
"error",
{
patterns: [
{
group: ["@company/*/src/**"],
message: "Import from package exports, not internal paths",
},
],
},
],
// Enforce import type for type-only imports
"@typescript-eslint/consistent-type-imports": [
"warn",
{ prefer: "type-imports" },
],
// Catch unused variables with underscore escape hatch
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
},
],
},
};Why good: Named exports enable better tree-shaking, preventing internal imports maintains package API boundaries, consistent type imports improve build performance, unused variable warnings catch dead code early with underscore escape hatch
---
ESLint 10 Migration
ESLint 10 was released February 6, 2026 and completely removes .eslintrc support. Before upgrading:
1. Remove .eslintrc files - Replace with eslint.config.ts 2. Remove .eslintignore - Use globalIgnores() in config 3. Update CLI scripts - Remove --no-eslintrc, --env, --rulesdir flags 4. *Remove `/ eslint-env /` comments - These now trigger errors in ESLint 10 5. Update Node.js* - ESLint 10 requires ^20.19.0 || ^22.13.0 || >=24
Key ESLint 10 changes:
- Config lookup starts from linted file directory (not cwd) - better monorepo support
- JSX reference tracking improved - fewer false positives with
no-unused-vars - Updated
eslint:recommendedwith new rules - Deprecated
Lintermethods removed (defineParser(),defineRule(),getRules()) - Built-in TypeScript definitions (no more
@types/eslintneeded)
ESLint 10 compatible config:
// eslint.config.ts - works with both ESLint 9.15+ and ESLint 10
import js from "@eslint/js";
import { defineConfig, globalIgnores } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import * as onlyWarnPlugin from "eslint-plugin-only-warn";
export default defineConfig(
globalIgnores(["dist/**", "node_modules/**"]),
js.configs.recommended,
eslintConfigPrettier,
tseslint.configs.recommended,
{
plugins: {
"only-warn": onlyWarnPlugin,
},
},
);Why good: This config works with both ESLint 9.15+ and ESLint 10 with zero changes — defineConfig() and globalIgnores() are the forward-compatible API
Prettier - Advanced Examples
TypeScript config files, experimental options, shared config usage, and ignore patterns. See core.md for the standard Prettier config.
Prerequisites: Understand Pattern 4 (Prettier Standard Config) from core.md first.
---
Pattern 9: Shared Config Usage
Reference a shared Prettier config from package.json to prevent per-package config drift:
// apps/my-app/package.json
{
"name": "my-app",
"prettier": "@company/prettier-config",
"devDependencies": {
"@company/prettier-config": "*"
}
}Why good: Single source of truth, no per-package formatting inconsistencies, zero config in each app
// BAD: Duplicated config in each package
// apps/client/.prettierrc
{ "printWidth": 80, "semi": true, "singleQuote": true }
// apps/dashboard/.prettierrc
{ "printWidth": 120, "semi": false, "singleQuote": true }Why bad: Different configs per package creates inconsistent formatting, developers switching between packages see formatting churn, code reviews show formatting noise
---
Pattern 10: TypeScript Config (v3.5+)
Prettier 3.5+ supports TypeScript configuration files for type-safe config. Requires Node.js 22.6.0+.
// packages/prettier-config/prettier.config.ts
import type { Config } from "prettier";
const config: Config = {
printWidth: 100,
useTabs: false,
tabWidth: 2,
semi: true,
singleQuote: false,
bracketSpacing: true,
arrowParens: "always",
endOfLine: "lf",
bracketSameLine: false,
};
export default config;Requirements:
- Node.js 22.6.0 or later
- Before Node.js v24.3.0, run with:
NODE_OPTIONS="--experimental-strip-types" prettier . --write
Supported file names: .prettierrc.ts, .prettierrc.mts, .prettierrc.cts, prettier.config.ts, prettier.config.mts, prettier.config.cts
---
Pattern 11: Experimental Options (v3.1+)
Experimental options address long-standing formatting debates. These may be removed or changed in future versions.
// prettier.config.mjs
const config = {
printWidth: 100,
semi: true,
singleQuote: false,
bracketSpacing: true,
// Experimental: ternary formatting (v3.1+)
experimentalTernaries: true,
// Experimental: object wrapping (v3.5+)
// "preserve" (default): keeps multi-line objects as-is
// "collapse": collapses objects that fit on one line
objectWrap: "preserve",
// Experimental: operator position (v3.5+)
// "end" (default): operators at end of line
// "start": operators at start of new lines
experimentalOperatorPosition: "end",
};
export default config;---
Pattern 12: Prettier Ignore Patterns
# .prettierignore
dist/
build/
coverage/
node_modules/
*.min.js
*.min.css
pnpm-lock.yaml
package-lock.json
bun.lockbWhy good: Prevents Prettier from touching generated files, lock files, and minified assets where formatting is irrelevant or harmful
---
Common Prettier Options
| Option | Default (v3.0+) | Notes |
|---|---|---|
printWidth | 80 | Consider 100 for wider screens |
tabWidth | 2 | |
useTabs | false | |
semi | true | |
singleQuote | false | |
trailingComma | "all" | Changed from "es5" in v3.0 |
bracketSpacing | true | |
bracketSameLine | false | Replaces jsxBracketSameLine |
arrowParens | "always" | |
endOfLine | "lf" | |
objectWrap | "preserve" | v3.5+ experimental |
experimentalTernaries | false | v3.1+ experimental |
experimentalOperatorPosition | "end" | v3.5+ experimental |
# yaml-language-server: $schema=https://raw.githubusercontent.com/agents-inc/cli/main/src/schemas/metadata.schema.json
category: shared-tooling
slug: eslint-prettier
domain: shared
author: "@vince"
displayName: ESLint & Prettier
cliDescription: ESLint 9/10 flat config and Prettier formatting
usageGuidance: Use when configuring ESLint 9 flat config, Prettier formatting, shared linting configs, or migrating from legacy .eslintrc to flat config.
ESLint & Prettier Reference
Version reference and official documentation links. See SKILL.md for decision frameworks and red flags.
---
Version Reference
| Tool | Latest Stable | Key Feature |
|---|---|---|
| ESLint 9 | v9.39.4 | Flat config, defineConfig(), multithreaded linting |
| ESLint 10 | v10.0.3 | .eslintrc removed, file-based config lookup |
| Prettier | v3.8.1 | TS config files, experimental options |
| typescript-eslint | v8.57.1 | projectService (stable), shared configs |
| eslint-config-prettier | latest | Disables conflicting ESLint formatting rules |
| eslint-plugin-only-warn | latest | Converts errors to warnings |
---
Prettier Config File Precedence
Highest to lowest priority:
1. "prettier" key in package.json 2. .prettierrc (JSON/YAML) 3. .prettierrc.json, .prettierrc.yaml 4. .prettierrc.js, prettier.config.js 5. .prettierrc.mjs, prettier.config.mjs 6. .prettierrc.cjs, prettier.config.cjs 7. .prettierrc.ts, prettier.config.ts (v3.5+) 8. .prettierrc.toml
---
Official Documentation
Related skills
FAQ
Should I still use .eslintrc?
No. ESLint 10 (February 2026) removes .eslintrc support, so use ESLint 9+ flat config with defineConfig() from eslint/config now.
How do I stop ESLint and Prettier from conflicting?
Use eslint-config-prettier to disable formatting rules that conflict with Prettier.