--- id: wiki-2026-0508-eslint-static-analysis title: ESLint Static Analysis category: 10_Wiki/Topics status: verified canonical_id: self aliases: [ESLint, JS linter, static analysis, custom rule, AST, biome, oxlint] duplicate_of: none source_trust_level: A confidence_score: 1.0 verification_status: applied tags: [software-engineering, static-analysis, eslint, javascript, typescript, ast, lint] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: JavaScript / TypeScript framework: ESLint 9 / Biome / oxlint --- # ESLint Static Analysis ## 매 한 줄 > **"매 JS / TS 의 AST-based static analysis"**. 매 syntax + style + bug pattern 의 catch. 매 modern (2024+): 매 flat config + 매 typescript-eslint + 매 fast alternative (Biome, oxlint). 매 custom rule = 매 enforcement. ## 매 핵심 ### 매 mechanism - 매 source → AST (espree / @typescript-eslint/parser). - 매 visitor pattern 의 rule traverse. - 매 violation 의 fix suggestion (autofix). ### 매 modern (2024+) - **Flat config** (eslint.config.js): 매 .eslintrc legacy out. - **typescript-eslint v8**: 매 type-aware lint. - **Biome**: 매 Rust-based 25x faster. - **oxlint**: 매 even faster (50-100x). - **Stylistic plugin**: 매 ESLint core 의 style rule 의 spin off. ### 매 응용 1. **Coding standard**: 매 team consistency. 2. **Bug prevention**: 매 no-undef, no-shadow. 3. **Performance**: 매 react-hooks rules. 4. **Security**: 매 eslint-plugin-security. 5. **Custom**: 매 team-specific anti-pattern. ### 매 LLM era - **AI-assisted rule**: 매 LLM 의 rule generate. - **Hybrid**: 매 ESLint + Corgea / Snyk. - **Auto-fix**: 매 LLM 의 complex pattern. ## 💻 패턴 ### Flat config ```javascript // eslint.config.js import js from '@eslint/js'; import tseslint from 'typescript-eslint'; import stylistic from '@stylistic/eslint-plugin'; export default tseslint.config( js.configs.recommended, ...tseslint.configs.recommendedTypeChecked, { languageOptions: { parserOptions: { project: './tsconfig.json' }, }, plugins: { '@stylistic': stylistic }, rules: { '@stylistic/semi': ['error', 'always'], '@typescript-eslint/no-floating-promises': 'error', 'no-console': ['warn', { allow: ['warn', 'error'] }], }, }, ); ``` ### Custom rule (no console.log) ```javascript // .eslint-rules/no-console-log.js export default { meta: { type: 'problem', docs: { description: 'Disallow console.log (use logger)' }, fixable: 'code', schema: [], }, create(context) { return { 'CallExpression[callee.object.name="console"][callee.property.name="log"]'(node) { context.report({ node, message: 'Use logger.info instead of console.log', fix(fixer) { return fixer.replaceText(node.callee, 'logger.info'); }, }); }, }; }, }; ``` ### Custom — forbid hardcoded URL ```javascript export default { meta: { type: 'problem' }, create(context) { return { Literal(node) { if (typeof node.value === 'string' && /^https:\/\/internal\./.test(node.value)) { context.report({ node, message: 'Use env var for internal URL' }); } }, }; }, }; ``` ### Type-aware rule (no-floating-promise) ```typescript // 매 typescript-eslint 의 type info 의 use import { ESLintUtils } from '@typescript-eslint/utils'; export const noUnsafePromise = ESLintUtils.RuleCreator(name => name)({ name: 'no-unsafe-promise', meta: { type: 'problem', docs: { description: '...' }, schema: [], messages: { msg: '...' } }, defaultOptions: [], create(context) { const services = ESLintUtils.getParserServices(context); const checker = services.program.getTypeChecker(); return { AwaitExpression(node) { const type = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(node.argument)); // 매 type-based logic }, }; }, }); ``` ### CI integration (GitHub Actions) ```yaml - run: npx eslint . --max-warnings 0 --format json -o eslint.json - uses: ataylorme/eslint-annotate-action@v3 with: { report-json: eslint.json } ``` ### Pre-commit (lint-staged) ```json { "lint-staged": { "*.{ts,tsx}": ["eslint --fix", "prettier --write"] } } ``` ### Migrate to Biome (faster) ```json // biome.json { "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", "linter": { "enabled": true, "rules": { "recommended": true, "complexity": { "noForEach": "error" } } }, "formatter": { "enabled": true, "indentWidth": 2 } } // 매 npx @biomejs/biome lint . ``` ### oxlint (Rust, fastest) ```bash npx oxlint@latest . --deny correctness --deny perf # 매 50-100x faster than ESLint ``` ### Disable inline (justified) ```typescript // eslint-disable-next-line @typescript-eslint/no-explicit-any -- 매 third-party type 의 incomplete const data = response as any; ``` ### LLM-generated rule ```python def llm_generate_rule(description): prompt = f"""Generate an ESLint custom rule. Description: {description} Output JS module with meta + create.""" return llm.generate(prompt) ``` ## 매 결정 기준 | 상황 | Tool | |---|---| | Standard JS/TS | ESLint flat config | | Speed-critical CI | Biome / oxlint | | Type-aware | typescript-eslint | | Custom team rule | ESLint custom rule | | Format only | Prettier / Biome | | Security | + eslint-plugin-security / Snyk Code | **기본값**: 매 ESLint flat + 매 typescript-eslint + 매 Biome (format) + 매 lint-staged + 매 CI annotate. ## 🔗 Graph - 부모: [[Static-Analysis]] · [[Code-Quality]] - 변형: [[Custom-ESLint-Rules-Development]] · [[Biome]] · [[oxlint]] - 응용: [[CI CD]] - Adjacent: [[Prettier]] · [[TypeScript]] · [[Corgea]] ## 🤖 LLM 활용 **언제**: 매 codebase standard. 매 team scale. 매 anti-pattern enforce. **언제 X**: 매 prototype throwaway. ## ❌ 안티패턴 - **Disable everything**: 매 lint 의 useless. - **Old .eslintrc legacy** (post-2024): 매 flat config 의 migrate. - **No type-aware in TS**: 매 false confidence. - **Lint at PR only**: 매 friction → 매 pre-commit. - **No autofix**: 매 manual fatigue. ## 🧪 검증 / 중복 - Verified (ESLint v9 docs, typescript-eslint, Biome). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-04-20 | Auto-reinforced | | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — flat config + custom rule + Biome / oxlint + CI / pre-commit code |