---
id: wiki-2026-0508-lint-staged
title: lint-staged
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [lint staged, staged-lint, pre-commit-lint]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [git, hooks, lint, devops, pre-commit]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: javascript
  framework: husky
---

# lint-staged

## 매 한 줄
> **"매 git staged file 만 task 실행"**. 매 commit 마다 전체 repo 를 lint 하지 않고 — 매 staged set 만 골라 ESLint/Prettier/typecheck 를 빠르게. 2026 현재는 husky 9 + lint-staged 15 + Bun/Node 22 LTS 조합이 표준.

## 매 핵심

### 매 동작 원리
1. `git diff --cached --name-only` 로 staged file 추출.
2. Glob 매칭으로 task list 구성.
3. **Stash backup** → task 실행 → 변경된 file 자동 `git add` → stash restore.
4. Task 실패 시 stash 복구로 working tree 보존.

### 매 핵심 features (v15)
- **Concurrent**: 매 task list 를 병렬 실행 (default `true`).
- **Function config**: dynamic task — 매 staged file 수에 따라 분기.
- **TypeScript config**: `lint-staged.config.ts` 지원.
- **Bun support**: `bunx lint-staged` 직접 실행.

### 매 응용
1. Pre-commit 에서 ESLint+Prettier 만 staged 파일에.
2. Monorepo 에서 변경 package 만 typecheck.
3. Image staged 시 자동 imagemin 압축.

## 💻 패턴

### Basic (package.json)
```json
{
  "lint-staged": {
    "*.{js,ts,tsx,jsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml}": "prettier --write",
    "*.{png,jpg}": "imagemin-cli --replace"
  }
}
```

### TypeScript config (recommended 2026)
```ts
// lint-staged.config.ts
import type { Configuration } from 'lint-staged';

const config: Configuration = {
  '*.{ts,tsx}': (files) => [
    `eslint --fix --max-warnings=0 ${files.join(' ')}`,
    `prettier --write ${files.join(' ')}`,
    'tsc --noEmit',
  ],
  '*.{js,mjs,cjs}': 'eslint --fix',
  '*.{json,md,yml,yaml}': 'prettier --write',
};

export default config;
```

### Husky 9 hook (pre-commit)
```sh
# .husky/pre-commit
bunx lint-staged
```

### Monorepo turbo + lint-staged
```ts
export default {
  '*.{ts,tsx}': (files) => {
    const packages = new Set(
      files.map((f) => f.split('/').slice(0, 2).join('/'))
    );
    return [...packages].map((pkg) => `turbo run lint --filter=${pkg}`);
  },
};
```

### Skip on rebase / merge
```sh
# .husky/pre-commit
[ -n "$CI" ] && exit 0
[ -f "$(git rev-parse --git-dir)/MERGE_MSG" ] && exit 0
[ -f "$(git rev-parse --git-dir)/rebase-merge" ] && exit 0
bunx lint-staged
```

### Function config — typecheck only when many files
```ts
export default {
  '*.{ts,tsx}': (files) =>
    files.length > 5
      ? ['tsc --noEmit', 'eslint --fix']
      : [`eslint --fix ${files.join(' ')}`],
};
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| 작은 repo, 빠른 commit | `eslint --fix` + `prettier --write` 만 |
| Type 안전 critical | typecheck 추가 (whole project) |
| Monorepo | turbo/nx run-affected 와 결합 |
| CI 가 이미 lint | pre-commit 은 fast-only — typecheck 빼기 |

**기본값**: ESLint+Prettier on staged only, typecheck 는 CI 로.

## 🔗 Graph
- 부모: [[Git Hooks]] · [[husky]]
- 변형: [[pre-commit (Python)]] · [[simple-git-hooks]]
- 응용: [[ESLint]] · [[Prettier]] · [[CI_CD Pipeline]]
- Adjacent: [[Commit_History]] · [[Continuous Integration (지속적 통합, CI)]]

## 🤖 LLM 활용
**언제**: 매 commit 마다 빠른 lint feedback — 매 contributor 의 IDE 셋업 무관 일관 enforce.
**언제 X**: 매 Trunk-based + every-push CI 환경 — pre-commit 은 friction. 매 emergency hotfix 시 `--no-verify` 우회로 인한 false sense of safety 위험.

## ❌ 안티패턴
- **전체 repo lint 를 pre-commit 에**: 매 100 file 변경 commit 시 분 단위 대기. lint-staged 의 의미 무시.
- **typecheck whole project on every commit**: Monorepo 에서 30s+. CI 로 옮기기.
- **Skip without `[ -n "$CI" ]` guard**: CI 에서 husky 가 두 번 실행.
- **Auto-fix without re-staging**: lint-staged 는 fix 후 자동 stage — 매 manual git add 불필요.

## 🧪 검증 / 중복
- Verified (lint-staged v15 README, husky 9 docs, 2026 공식 사용 사례).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content with TS config + monorepo patterns |
