React Doctor로 React 코드 건강 점검하고 코딩 에이전트 가르치기
코딩 에이전트와 함께 React 코드를 짜다 보면 묘한 위화감이 들 때가 있습니다. 코드는 분명히 동작하고 타입도 맞는데, useEffect 안에서 상태를 폭포처럼 줄줄이 갱신하거나 dangerouslySetInnerHTML을 별 고민 없이 넣어두는 식이죠. 에이전트 입장에서는 “요구사항을 만족시키는 코드”를 짠 것이지만, 우리 입장에서는 “리뷰 코멘트가 쏟아질 코드”입니다.
이 간극을 메우는 도구가 Million.co에서 만든 React Doctor입니다. 한 줄짜리 명령으로 React 프로젝트를 진단해서 0~100 사이의 건강 점수를 매겨주고, 우리가 쓰고 있는 코딩 에이전트에 React 모범 사례를 직접 가르쳐주기까지 합니다. 이번 글에서는 React Doctor를 어떻게 쓰는지, 그리고 왜 이런 도구가 AI 시대에 자리를 잡아가고 있는지를 같이 살펴보겠습니다.
React Doctor란
React Doctor는 React 코드베이스에서 보안, 성능, 정확성, 아키텍처 문제를 한 번에 스캔하는 오픈소스 진단 도구입니다. ESLint나 Biome 같은 일반 린터와 결이 조금 다른데요, React 특유의 안티패턴(useEffect 오용, 파생 상태, 비싼 재계산 등)에 특화된 60개 이상의 규칙을 묶어 두고 프로젝트 설정에 따라 알아서 켜고 끕니다.
내부적으로는 Oxc의 oxlint 위에 React Doctor 자체 플러그인을 얹어 빠르게 검사하고, 거기에 죽은 코드(unused exports, types, 중복 파일 등)를 찾는 패스를 병렬로 돌립니다. 두 결과가 합쳐져 심각도에 따라 가중치가 매겨지고, 0~100 점의 건강 점수가 나오죠. 75점 이상이면 Great, 50~74점이면 Needs work, 50점 미만은 Critical 등급입니다.
여기에 한 가지가 더 있는데요. react-doctor install 명령으로 우리 시스템에 깔린 Claude Code, Cursor, Codex 같은 코딩 에이전트의 컨텍스트 파일에 같은 규칙 세트를 룰 파일 형태로 깔아둘 수 있다는 점입니다. 진단에 더해 에이전트가 코드를 짤 때 참고할 규칙까지 같은 출처로부터 함께 깔린다는 게 보통 린터와 갈리는 지점이에요.
첫 진단 실행하기
설치 과정 자체가 없습니다. 프로젝트 루트에서 한 줄만 실행하면 끝이에요.
npx -y react-doctor@latest .
실행하면 React Doctor가 우선 프레임워크(Next.js, Vite, Remix 등)와 React 버전, React Compiler 사용 여부를 자동으로 감지합니다. 그다음 lint와 dead code 분석을 병렬로 돌리고, 각 진단에 위반된 규칙 ID와 간단한 설명을 출력하죠. 마지막에 점수와 등급이 따라옵니다.
영향받은 파일과 줄 번호까지 보고 싶다면 --verbose 플래그를 추가합니다.
npx -y react-doctor@latest . --verbose
이 옵션을 켜면 각 규칙별로 어떤 파일의 몇 번째 줄에서 문제가 발생했는지 표시되어, 곧장 에디터로 점프해서 고치기가 편합니다. 처음 도입할 때는 verbose 모드로 한 번 훑어 본 뒤, 평소에는 점수만 보면서 추세를 관리하는 식이 잘 어울립니다.
어떻게 동작하는가
React Doctor의 분석은 두 갈래로 갈라져 동시에 진행됩니다.
첫 번째 갈래는 lint입니다. 상태와 효과(state & effects), 성능, 아키텍처, 번들 크기, 보안, 정확성, 접근성, 그리고 Next.js나 React Native 같은 프레임워크별 카테고리까지 60개가 넘는 규칙이 들어 있어요. 핵심은 우리 프로젝트의 설정을 보고 알맞은 규칙만 켠다는 점입니다. Next.js 프로젝트가 아니면 Next.js 규칙은 자동으로 비활성화되고, React Compiler를 쓰고 있다면 컴파일러가 어차피 처리할 메모이제이션 관련 규칙은 꺼지는 식이죠. 우리가 직접 켜고 끄는 ESLint 설정의 피로를 상당 부분 줄여줍니다.
두 번째 갈래는 죽은 코드 탐지입니다. 사용되지 않는 파일, export, 타입, 그리고 중복된 코드를 찾아내는데요, 내부적으로는 knip을 활용합니다. 리팩터링이 잦은 React 프로젝트에서는 안 쓰는 컴포넌트와 유틸이 빠르게 쌓이기 마련이라 이 부분만으로도 큰 도움이 됩니다.
두 결과가 모인 뒤에는 우리가 지정한 무시 규칙으로 한 번 거르고, 남은 진단을 심각도에 따라 가중치를 매겨 점수를 산출합니다. 에러는 경고보다 점수에 미치는 영향이 크고, 점수가 낮을수록 손볼 곳이 많다는 뜻이죠.
한 가지 짚어둘 점이 있습니다. 공식 사이트와 README는 “Let coding agents diagnose and fix your React code”라는 헤드라인을 내걸고 있어서 마치 React Doctor 자체가 LLM 기반 도구처럼 보이지만, 실제로 진단을 수행하는 주체는 oxlint와 knip이라는 정적 분석 도구입니다. 결과가 결정적이고 실행도 빠르며, 별도의 모델 API 키가 필요하지 않아요. LLM이 등장하는 시점은 진단 결과를 받아 코드를 수정하는 단계뿐이고, 그것도 우리가 쓰던 코딩 에이전트가 알아서 호출하는 식이죠.
그래서 React Doctor의 차이점은 분석 엔진의 똑똑함이라기보다 워크플로우 통합 쪽에 있다고 보는 게 정확합니다. 진단에 쓰는 규칙 세트와 에이전트가 코드를 생성할 때 참고하는 규칙 세트를 한 출처로 묶어, 사후 검증과 사전 가이드가 어긋나지 않게 한다는 게 핵심이에요.
코딩 에이전트에 React 규칙 설치하기
다음 명령을 한 번 실행해보세요.
npx -y react-doctor@latest install
React Doctor가 우리 시스템에 어떤 코딩 에이전트가 깔려 있는지 탐지합니다. $PATH에 있는 CLI 바이너리와 $HOME 아래의 설정 디렉토리(~/.claude, ~/.cursor, ~/.codex 등)를 둘 다 살펴서 합집합으로 잡아내죠. Claude Code, Codex, Cursor, Factory Droid, Gemini CLI, GitHub Copilot, Goose, OpenCode, Windsurf, Roo Code, Cline 등 50개가 넘는 에이전트를 지원합니다.
원하는 에이전트만 골라 설치할지 묻는 프롬프트가 뜨고, 모두 설치하려면 --yes 플래그를 붙이면 됩니다. 설치되는 내용은 각 에이전트의 에이전트 룰 파일 규약에 맞춰진 React 모범 사례 가이드인데요, 예를 들어 Claude Code라면 ~/.claude 또는 프로젝트의 CLAUDE.md에, Cursor라면 .cursor/rules/에 적절한 형식으로 들어갑니다.
린터는 사람이 코드를 짠 다음에 잘못을 짚어주는 사후 도구지만, 에이전트 룰 파일은 코드를 짜기 전에 미리 읽히는 “사전 처방”입니다. React Doctor가 사후에(react-doctor .) 잡아내는 문제와 사전에(react-doctor install) 막는 문제가 같은 규칙 세트에서 나오기 때문에, 에이전트가 짜는 코드와 우리가 나중에 검증하는 기준이 자연스럽게 맞아떨어집니다.
GitHub Actions로 PR마다 진단하기
매번 손으로 돌리는 건 금세 잊히기 마련이라, CI에 끼워두는 게 효과적입니다. React Doctor는 GitHub Actions를 일급으로 지원해요.
name: React Doctor
on:
pull_request:
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: millionco/react-doctor@main
with:
diff: main
github-token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0이 필요한 이유는 diff 모드 때문입니다. diff: main을 지정하면 React Doctor가 main 브랜치 대비 변경된 파일만 스캔하기 때문에 PR 진단이 빠르게 끝나고, 무관한 기존 코드의 잡음도 끼지 않습니다. github-token을 함께 넘겨두면 발견된 진단을 PR 코멘트로 직접 남겨주죠. 리뷰어가 굳이 액션 로그까지 들춰보지 않아도 됩니다.
앞서 짚었듯이 React Doctor 자체는 LLM을 호출하지 않으므로 OpenAI나 Anthropic 같은 모델 API 키를 시크릿에 등록할 필요가 없습니다. 위 예제의 GITHUB_TOKEN은 발견된 진단을 PR 코멘트로 남길 때 쓰는 GitHub용 토큰일 뿐이에요. 덕분에 다른 AI 기반 CI 도구들과 달리 토큰 비용이나 레이트 리밋을 신경 쓸 일도 없습니다.
기본 동작은 에러가 발견되면 빌드를 실패시키는 것인데, 이걸 누그러뜨리려면 fail-on: warning이나 fail-on: none으로 임계값을 조정할 수 있습니다. 처음 도입할 때는 none으로 시작해서 점수만 모니터링하다가, 어느 정도 안정화되면 error로 죄어가는 흐름이 부담이 적습니다. 액션의 score 출력을 후속 스텝으로 넘기면 슬랙 알림이나 대시보드 연동도 곧장 가능하고요.
설정과 무시 규칙
기본값만으로도 잘 동작하지만, 우리 코드베이스 사정에 맞게 다듬고 싶을 때는 프로젝트 루트에 react-doctor.config.json을 두면 됩니다.
{
"ignore": {
"rules": ["react/no-danger", "knip/exports"],
"files": ["src/generated/**"]
}
}
ignore.rules에는 진단 결과의 plugin/rule 형식 ID를 그대로 적고, ignore.files에는 글롭 패턴으로 제외할 경로를 넣습니다. package.json의 "reactDoctor" 키에 같은 내용을 넣어도 동작하니, 설정 파일 개수를 늘리고 싶지 않으면 그쪽을 골라도 됩니다.
또 한 가지 편한 점은 우리 프로젝트가 이미 가지고 있는 무시 규칙을 자동으로 존중한다는 부분입니다. .gitignore, .eslintignore, .oxlintignore, .prettierignore는 물론이고, GitHub의 linguist가 보는 .gitattributes의 linguist-vendored와 linguist-generated 표시까지 따라줘요. 즉, 이미 “내 코드가 아니다”라고 표시해둔 곳은 React Doctor도 손대지 않습니다. 별도의 ignore 목록을 또 관리할 필요가 없는 거죠.
특정 줄만 잠시 무시하고 싶다면 인라인 주석을 씁니다.
// react-doctor-disable-next-line react-doctor/no-cascading-set-state
useEffect(() => {
setA(value);
setB(value);
setC(value);
}, [value]);
react-doctor-disable-line과 react-doctor-disable-next-line 두 가지를 제공하고, JSX 내부에서는 블록 주석으로도 동일하게 동작합니다. 기존에 쓰던 // eslint-disable*나 // oxlint-disable* 주석도 그대로 인식해주기 때문에 마이그레이션 부담이 거의 없습니다.
JSON 출력으로 자동화하기
사람이 보기 좋은 출력 외에 기계가 파싱하기 좋은 모드도 있습니다. --json 플래그를 추가하면 한 덩어리의 JSON 객체가 표준 출력으로 떨어집니다.
npx -y react-doctor@latest . --json | jq '.summary'
{
"errorCount": 3,
"warningCount": 12,
"affectedFileCount": 8,
"totalDiagnosticCount": 15,
"score": 78,
"scoreLabel": "Great"
}
schemaVersion이 박혀 있어 스키마 변경에 대비할 수 있고, 에러가 발생해도 ok: false인 유효한 JSON을 돌려주기 때문에 셸 스크립트에서 안전하게 다루기 좋습니다. 이걸 활용하면 점수를 슬랙으로 던지거나 자체 대시보드에 모아 추세를 관찰하는 식으로 확장할 수 있죠.
좀 더 깊이 있게 자동화하고 싶다면 Node.js API도 제공됩니다.
import { diagnose } from "react-doctor/api";
const result = await diagnose("./path/to/your/react-project");
console.log(result.score); // { score: 82, label: "Great" }
console.log(result.diagnostics); // Diagnostic 객체 배열
console.log(result.project); // 감지된 프레임워크, React 버전 등
CLI를 거치지 않고 우리 도구 안에서 직접 호출할 수 있어서, 사내에 React 코드 품질을 다루는 별도 봇이나 대시보드를 만들 때 토대로 쓸 수 있습니다.
마치며
React Doctor는 한 도구 안에 두 가지 역할을 같이 담고 있습니다. 한 줄 명령에 점수와 진단을 돌려주는 친숙한 린터 역할, 그리고 같은 규칙을 코딩 에이전트의 룰 파일로 깔아두어 에이전트가 코드를 생성할 때 참고하게 만드는 역할이죠. 사후 검증과 사전 가이드가 같은 규칙 세트를 공유하기 때문에, 에이전트가 내놓는 코드와 우리가 검증하는 기준이 한 방향을 보게 됩니다.
React 프로젝트가 있으시면 한 번 돌려보세요. 점수만 확인해 봐도 그동안 미뤄둔 리팩터링의 우선순위가 또렷해집니다. 평소 코딩 에이전트와 함께 일하시는 분이라면 react-doctor install을 한 번 거쳐 두시는 것도 권합니다.
더 자세한 내용은 React Doctor 공식 사이트를 참고하세요.
This work is licensed under
CC BY 4.0