TRENDSHIFT DEEP-DIVE · 2026.05.27 · google/eng-practices

google/eng-practices —
구글이 20년간 쌓아 올린 "코드리뷰 헌법"

2025년 11월 아카이브되었지만 오늘도 트렌딩 11위에 올라 있는 레포. 코드가 한 줄도 없다. 그 대신 "코드리뷰를 어떻게 해야 하는가"에 대한 구글 사내 가이드 — 리뷰어 가이드 7편, 작성자 가이드 4편 — 이 마크다운으로 정리되어 있다. ⭐ 20.5k · CC-BY 3.0 · 모든 언어·모든 회사에 적용 가능한 "코드리뷰의 표준."

1프로젝트 한줄 요약

코드는 없다. 사상(philosophy)이 있다.

구글 사내에서 모든 신입 엔지니어가 입문서로 읽는 "코드리뷰 가이드라인"을 외부에 공개한 것. 리뷰어가 무엇을 봐야 하는지, CL(Change List, 풀리퀘) 작성자는 어떻게 행동해야 하는지, 의견 충돌은 어떻게 풀어야 하는지를 "규칙이 아니라 원칙"으로 풀어 썼다.

한 줄로 말하면

"코드리뷰의 헌법" — 변호사 매뉴얼이 아니라 "사법 정신"을 가르치는 책

대부분의 회사는 PR 템플릿, 리뷰 체크리스트 같은 "규칙"을 만든다. 구글의 이 문서는 다르다. "왜 코드리뷰를 하는가", "리뷰어와 작성자의 역할은 무엇인가", "갈등이 생기면 어떤 원칙으로 푸는가" — 실무 규칙 뒤에 깔려 있어야 할 정신을 먼저 정의한다.

그래서 짧다. 전체 분량이 14개 마크다운 파일, A4 50장 정도. 그런데 별이 20.5k. 사람들은 코드리뷰 도구가 아니라 "리뷰를 둘러싼 인간관계의 매뉴얼"을 찾고 있었다는 뜻이다.

용어
CL (ChangeList)
구글 사내 용어로, GitHub의 "Pull Request", GitLab의 "Merge Request"와 같은 개념. 한 번에 제출되는 자기완결적(self-contained) 코드 변경 묶음을 가리킨다. 이 문서 전반에 CL이라는 표현이 등장한다.
용어
LGTM (Looks Good To Me)
리뷰어가 CL을 승인할 때 쓰는 관용 표현. "내가 보기엔 좋다 → 머지 OK"라는 뜻. 구글 내부에서 만들어져 업계 전반의 표준 용어가 됐다.

2왜 지금도 주목받는가

2019년 공개 → 2025년 11월 아카이브 → 그래도 매일 트렌딩에 오르는 이유.

이 레포는 사실 업데이트가 멈춘 지 오래된 문서다. 2025년 11월 21일자로 read-only 아카이브 처리됐다. 그런데도 매일 누군가가 별을 누른다. 이유는 세 가지다.

① "왜 우리 팀 리뷰는 항상 싸움이 되는가"의 답이 여기 있다

리뷰가 길어지면 본질이 아니라 감정싸움이 된다. 이 문서는 "리뷰어 vs 작성자"가 아니라 "코드 헬스(code health) vs 시간"이라는 더 추상적인 축으로 갈등 구조를 재정의한다. 사람을 비판하는 게 아니라 "장기적으로 코드가 더 건강해지는가"를 보자는 것. 이 관점 하나만 팀에 깔려도 리뷰 문화가 180도 바뀐다.

② 모든 언어/모든 도구에서 통한다

"Go 코드는 이렇게 리뷰하라", "React PR은 이런 체크리스트로" 같은 도구 의존적 문서가 아니다. 리뷰 자체의 메타 원칙을 다루기 때문에, GitHub·GitLab·Phabricator·Gerrit 어느 환경에서도 그대로 적용 가능하다. CC-BY 3.0 라이선스라 회사 위키에 그대로 복사·번역해도 된다.

③ AI 코딩 시대에 오히려 더 중요해졌다

2026년 현재 Claude Code, Cursor, Copilot이 PR을 자동 생성한다. 그러면 리뷰어의 역할이 더 무거워진다 — AI가 생성한 1000줄짜리 PR을 그냥 LGTM할 수는 없으니까. 이 문서가 말하는 "작은 CL 원칙", "every line 원칙", "Why를 묻는 코드리뷰"가 AI 시대의 안전벨트 역할을 하게 됐다. 트렌드 카테고리에 #AI agent가 없는데도 11위에 오른 건 그 때문이다.

경쟁/유사 자료와의 비교

자료스타일이 문서와 차이
《Code Complete》 (Steve McConnell)"좋은 코드"의 책이 문서는 "좋은 코드"가 아니라 "좋은 리뷰"에 초점
SmartBear《Best Kept Secrets of Peer Code Review》리뷰 통계·연구 기반이 문서는 통계보다 의사결정 원칙 중심
회사별 PR 템플릿체크리스트이 문서는 체크리스트가 아니라 사상을 가르침
《The Pragmatic Programmer》개인 엔지니어링 태도이 문서는 팀 vs 개인의 속도 트레이드오프를 정면으로 다룸

3"기술 스택" — 사실은 문서 구조 그 자체

코드가 없으니 기술 스택도 없다. 대신 "문서가 어떻게 짜여 있는가"가 곧 이 레포의 설계다.

이 레포는 review/ 폴더 하나에 모든 콘텐츠가 들어 있다. Jekyll 기반 GitHub Pages로 빌드되어 google.github.io/eng-practices에 호스팅된다. 빌드 설정은 _config.yml 한 파일이 전부.

FRONT (정적 사이트)

Jekyll + GitHub Pages

마크다운 → HTML 변환은 GitHub Pages에 내장된 Jekyll이 처리한다. 별도 빌드 파이프라인이 없다. master 브랜치에 푸시하면 끝.

CORE (콘텐츠)

마크다운 14개 파일 — "리뷰어 가이드"와 "작성자 가이드" 두 축

전체 콘텐츠가 리뷰어용 7개 문서작성자용 4개 문서로 양분되어 있다. "리뷰는 양쪽이 같은 책을 읽어야 한다"는 사상이 폴더 구조에 그대로 드러난다.

META (라이선스 · 메타데이터)

CC-BY 3.0

코드용 라이선스(Apache, MIT)가 아니라 저작물용 라이선스를 쓴다. 이 레포가 "코드 프로젝트"가 아니라 "문서 프로젝트"임을 라이선스로 선언한 셈. 회사 위키에 복사하고 번역해도 출처만 밝히면 된다.

4"아키텍처" — 코드리뷰 의사결정의 흐름도

코드 아키텍처 대신, 이 문서가 가르치는 리뷰 의사결정 트리를 그려본다.

┌─────────────────────────────────────────────────────────┐ │ CL(=PR) 도착 — 리뷰어 입장 │ └────────────────────┬────────────────────────────────────┘ │ ┌────────────▼────────────┐ │ 1. CL 크기 확인 │ │ 너무 크면 → "split해줘" │ ← small-cls.md └────────────┬────────────┘ │ OK ┌────────────▼────────────┐ │ 2. CL 설명 읽기 │ │ "왜"가 있나? 없으면 보강│ ← cl-descriptions.md └────────────┬────────────┘ │ OK ┌────────────▼────────────────────────────┐ │ 3. 모든 라인을 본다 (every-line) │ │ ├─ Design : 시스템에 맞는가? │ │ ├─ Function : 의도대로 동작? │ │ ├─ Complexity : 더 단순하게? │ │ ├─ Tests : 적절한 테스트? │ │ ├─ Naming : 이름 명확? │ │ ├─ Comments : 왜(why)를 설명? │ │ ├─ Style : 스타일 가이드 준수? │ │ └─ Docs : 문서 업데이트? │ ← looking-for.md └────────────┬────────────────────────────┘ │ ┌────────▼────────┐ │ "코드 헬스가 │ │ 개선되는가?" │ ← standard.md (헌법 1조) └────────┬────────┘ │ ┌────────────┼─────────────┐ Yes 유보 No │ │ │ ▼ ▼ ▼ LGTM Nit/Optional/ reject + FYI 라벨 코멘트 구체적 이유 │ ▼ ┌──────────────────┐ │ 작성자 응답 │ │ • 코드 수정 │ │ • 코멘트 토론 │ │ • 충돌 시 escalate│ ← handling-comments.md └──────────────────┘

핵심 설계 패턴 1: "단일 헌법 조항"

이 문서 전체에서 가장 중요한 한 문장:

STANDARD (standard.md)
"리뷰어는, CL이 완벽하지 않더라도 시스템의 전체적인 코드 헬스를 분명히 개선하는 상태가 되었다면 일반적으로 승인을 해야 한다."

이게 "수석 원칙(senior principle)"이다. 완벽을 추구하지 말고 지속적 개선(continuous improvement)을 추구하라는 것. 모든 다른 규칙은 이 조항 아래에 종속된다.

핵심 설계 패턴 2: "팀 속도 > 개인 속도"

리뷰가 늦어지면 개인은 다른 일을 할 수 있어서 효율적으로 보인다. 그러나 팀 관점에서는 손해다. 그래서 이 문서는 "리뷰 응답 시간은 영업일 1일 이내"라는 강한 룰을 박는다. 단, 본인이 "집중 작업 중"이라면 끊기지 말 것. 끊김 비용이 더 크기 때문.

핵심 설계 패턴 3: "작은 CL의 우월성"

이 문서가 거의 신앙처럼 반복하는 주장: "CL은 작을수록 좋다." 이유는 8가지로 정리된다.

가이드라인은 약 "100줄이 적당, 1000줄은 너무 큼". 다만 줄 수보다 "한 가지 일만 하는가(one self-contained change)"가 더 중요한 판단 기준이다.

비유

큰 PR을 한 번에 리뷰하는 건 장편소설을 한 호흡에 정독하는 것과 같다. 작은 PR을 연속으로 리뷰하는 건 단편소설집을 한 편씩 끊어 읽는 것과 같다. 같은 분량인데 후자는 디테일을 다 잡아내고, 전자는 클라이맥스도 졸면서 넘긴다.

5디렉토리 구조 해부

"이 폴더 구조 자체가 가르침이다."

eng-practices/ ├── README.md ← 진입점: "CL이란 무엇인가" 같은 용어 안내 ├── LICENSE ← CC-BY 3.0 (저작물 라이선스) ├── _config.yml ← Jekyll/GitHub Pages 설정 (한 파일) └── review/ ├── index.md ← 코드리뷰 개요 + "리뷰어가 무엇을 보는가" 요약 ├── emergencies.md ← 긴급 상황(=hot-fix) 예외 규칙 │ ├── reviewer/ ──── 리뷰어용 가이드 7편 ──── │ ├── index.md : 리뷰어 가이드 진입점 │ ├── standard.md : 🏛️ "헌법 1조" — 코드 헬스 원칙 │ ├── looking-for.md : 리뷰에서 무엇을 봐야 하는가 (디자인·기능·복잡도·…) │ ├── navigate.md : 큰 CL을 어떤 순서로 읽을 것인가 │ ├── speed.md : 응답은 1영업일 이내. 왜 빨라야 하는가 │ ├── comments.md : 리뷰 코멘트 쓰는 법 (Nit:/Optional:/FYI: 라벨) │ ├── pushback.md : 작성자가 반박해 올 때 대응법 │ └── ... │ └── developer/ ──── CL 작성자용 가이드 4편 ──── ├── index.md : 작성자 가이드 진입점 ├── cl-descriptions.md: 좋은 CL 설명 쓰는 법 (What + Why) ├── small-cls.md : 작은 CL의 8가지 이점, 쪼개는 4가지 전략 └── handling-comments.md: 리뷰 코멘트에 대응하는 법 (감정·논쟁 관리)

핵심은 두 폴더로 나뉜다는 것이다. 리뷰어와 작성자는 같은 사건을 다른 관점에서 본다. 그래서 같은 사건(=CL 충돌)에 대해 양쪽 문서가 서로 다른 조언을 한다. 그러나 결론은 항상 같은 "헌법 1조"로 수렴한다 — standard.md의 "코드 헬스 개선" 원칙.

6핵심 챕터 미리보기 — 사실상 이 책의 요약

14개 문서 중 가장 자주 인용되는 5개 챕터를 한 페이지로 압축.

6-1. standard.md — "코드 헬스가 헌법이다"

RULE
완벽한 코드는 없다. 더 나은 코드만 있을 뿐.

리뷰어는 "perfect"를 요구해서는 안 된다. continuous improvement를 추구해야 한다. CL이 시스템을 개선한다면 며칠씩 붙잡고 폴리싱하지 말 것.

중요한 부속 원칙:

6-2. looking-for.md — 리뷰어 체크리스트 8개 영역

영역핵심 질문
Design이 변경이 시스템에 어울리는가? 라이브러리에 들어가야 할 코드가 아닌가?
Functionality의도대로 동작하는가? 엣지케이스, 동시성 문제는?
Complexity더 단순할 수 없나? "미래에 필요할 것 같다"는 이유의 과잉 설계는 거부
Tests의미 있는 단위/통합/E2E 테스트가 함께 있는가?
Naming이름이 충분히 정보적인가? 너무 길지 않은가?
Comments"what"이 아니라 "why"를 설명하는가?
Style스타일 가이드 준수? 스타일 변경과 기능 변경을 한 CL에 섞지 말 것
DocumentationREADME, g3doc, generated docs 업데이트되었는가?
Consistency기존 코드 패턴·스타일 가이드와 일관성 있는가? 가이드에 없을 경우 기존 코드 스타일을 따를 것

그리고 가장 강한 한 줄: "Every line. 사람이 작성한 모든 라인을 본다." 자동 생성 코드, 데이터 파일이 아니라면 한 줄도 건너뛰지 말 것. 이해 안 되면 작성자에게 물어볼 것 — 당신이 이해 못한 코드는 미래의 개발자도 이해 못한다.

6-3. speed.md — "리뷰는 빨라야 한다, 단 본인은 끊기지 말 것"

응답 시간 룰: 한 영업일 이내. 아침에 PR을 받으면 그날 안에, 저녁에 받으면 다음날 아침 첫 일과로 응답.

예외: 본인이 집중 작업 중이면 끊지 말 것. 점심·미팅 후 자연스러운 break-point에 응답.

"LGTM with comments": 사소한 수정만 남았다면 "LGTM, 단 코멘트 반영해줘"로 미리 승인. 작성자가 다른 타임존이라면 특히.

큰 CL 거절권: 너무 큰 CL은 "쪼개와"라고 돌려보내는 게 정당한 응답이다.

6-4. comments.md — 리뷰 코멘트는 "사람"이 아니라 "코드"를 향한다

BAD
"왜 당신은 여기서 쓰레드를 썼나요? 명백히 동시성이 필요 없는데요."

주체가 "당신"이다. 사람을 비난한다.

GOOD
"여기의 동시성 모델은 성능 이득이 보이지 않는데 복잡도를 더하고 있다. 성능 이득이 없다면 단일 스레드가 낫다."

주체가 "코드"다. 그리고 왜(why)를 함께 설명한다.

코멘트는 심각도 라벨을 붙일 것:

이 라벨이 없으면 작성자는 모든 코멘트를 필수로 받아들여 좌절한다. 한 줄 라벨이 갈등의 90%를 줄인다.

6-5. cl-descriptions.md — CL 설명은 "What + Why"가 의무다

"Fix bug", "Fix build", "Phase 1" — 모두 나쁜 CL 설명의 실제 예시다.

GOOD CL DESCRIPTION
RPC: Remove size limit on RPC server message freelist.

Servers like FizzBuzz have very large messages and would benefit from reuse. Make the freelist larger, and add a goroutine that frees the freelist entries slowly over time, so that idle servers eventually release all freelist entries.

구조: ① 첫 줄 = 명령문으로 압축 (Delete X. / Add Y. / Replace Z.) → ② 본문 = 왜(why), 어떤 trade-off, 어떤 한계를 함께 설명. 미래의 누군가가 git log를 grep할 때 발견할 수 있도록.

7학습 포인트 — 이 문서에서 무엇을 배울 수 있나

기술이 아니라 "관점"이 학습 대상이다.

학습 포인트 ①: 리뷰의 목적을 다시 정의하기

"버그 잡기"가 아니다. "장기적 코드 헬스 유지"다. 이 관점이 깔리면 다음과 같은 변화가 생긴다:

학습 포인트 ②: 갈등을 escalation 체인으로 풀기

리뷰어와 작성자가 충돌하면? 이 문서가 제시하는 순서:

  1. 코멘트로 합의 시도
  2. 안 되면 화상 미팅 / 페이스 투 페이스 (단, 결과는 CL 코멘트에 기록)
  3. 그래도 안 되면 더 넓은 팀 토론 → 테크리드 → 코드 오너 → 엔지니어링 매니저 순으로 escalation
  4. 핵심: "CL을 며칠씩 방치하지 말 것"

학습 포인트 ③: "Nit:" 한 단어의 위력

실무에서 가장 즉시 적용 가능한 팁. PR 코멘트 앞에 Nit:를 붙이는 습관 하나만 들여도 팀 분위기가 바뀐다. 작성자는 "이건 안 고쳐도 됨"을 알 수 있고, 리뷰어는 "내가 이건 그냥 취향임을 인정함"을 표시할 수 있다.

학습 포인트 ④: PR을 작게 쪼개는 4가지 전략

전략설명예시
Stacking작은 CL을 머지 안 기다리고 그 위에 다음 CL을 쌓음git rebase, jj 등으로 PR 체인
By Files파일 묶음별로 다른 리뷰어 배정proto 변경 + 사용 코드 → 두 PR로 분리
Horizontal레이어로 자르기 (UI/API/Service/DB)먼저 API 스텁만, 그 다음 구현
Vertical기능 단위(end-to-end)로 자르기곱셈/나눗셈을 별도 PR로

학습 포인트 ⑤: 댓글이 아니라 코드를 고친다

리뷰어가 "이거 이해 안 됨"이라고 하면 작성자의 첫 반응은 무엇이어야 할까? 설명 댓글이 아니다. 코드를 더 명확하게 고친다. 안 되면 코드 주석을 단다. 그것도 안 되면 그제서야 PR 댓글로 설명한다. 이유는 단순하다 — PR 댓글은 1년 뒤 코드를 읽는 사람에게는 안 보이기 때문.

8하드웨어/시스템 요구사항

"이 레포에는 코드가 없다. 그래서 요구사항도 없다."

로컬에서 실행할 게 없다. 문서를 읽기만 하면 된다. 굳이 빌드해보고 싶다면 Jekyll만 설치하면 GitHub Pages와 동일한 사이트를 로컬에서 띄울 수 있다.

로컬에서 사이트 빌드하기 (선택)

Ruby 2.7+ → gem install jekyll bundler → 레포 클론 → bundle exec jekyll servelocalhost:4000 접속.

하지만 솔직히 공식 호스팅 페이지를 그냥 읽는 게 더 편하다.

9직접 해볼 수 있는 실습 과제

"읽기"가 아니라 "내 팀에 적용"이 진짜 학습이다.

난이도 ★

1. 다음 내가 작성할 PR 설명을 이 가이드대로 다시 쓰기

"버그 수정" 같은 한 줄 설명을 쓰지 말고 — 첫 줄에 명령문, 본문에 "왜"를 적는다. cl-descriptions.md의 GOOD 예시를 그대로 모방해본다.

난이도 ★

2. 리뷰 코멘트에 라벨 붙이기 1주일 챌린지

한 주 동안 내가 다는 모든 리뷰 코멘트 앞에 Nit:, Optional:, Consider:, FYI: 중 하나를 붙인다. 일주일 후 작성자들의 반응 변화를 관찰한다.

난이도 ★★

3. 큰 PR 분해 시뮬레이션

최근 내가 보낸 가장 큰 PR 1개를 가져와서, small-cls.md의 4가지 전략(Stacking/By Files/Horizontal/Vertical) 중 어떤 걸로 쪼갰어야 했는지 사후 분석한다. 다음에 같은 작업을 한다면 어떤 순서로 PR을 보낼지 종이에 그려본다.

난이도 ★★★

4. 우리 팀 PR 가이드를 이 레포 구조로 다시 쓰기

회사 위키의 "PR 작성 규칙"을 리뷰어용 / 작성자용 두 폴더로 분리한다. 양쪽 모두에 같은 "헌법 1조"(코드 헬스 원칙)를 새긴다. CC-BY 3.0이므로 이 레포에서 그대로 인용해도 된다.

난이도 ★★★★

5. AI PR 리뷰 봇에 이 가이드 적용

Claude / Copilot이 자동으로 PR을 만드는 환경에서, looking-for.md의 8개 영역을 그대로 체크리스트로 만들어 AI에게 자기검증을 시킨다. AI가 만든 PR에서 "Every line" 원칙을 어떻게 보존할지 사내 룰을 작성한다.

10관련 기술 심화 학습 로드맵 (4주)

이 레포는 "출발선"이다. 4주 동안 코드리뷰의 전체 우주를 돌아본다.

주차주제학습 자료
1주차이 레포 정독review/ 폴더의 14개 마크다운 전체. 메모 작성하며 읽기. Nit/Optional 라벨을 본인 PR에 적용 시작
2주차스타일 가이드 깊게google/styleguide — 본인이 자주 쓰는 언어(Python, TS, Go, …) 하나만 정독
3주차좋은 코드 자체에 대한 책《Code Complete 2》 Ch.20-22 (코드리뷰/페어 프로그래밍) + 《The Pragmatic Programmer》
4주차리뷰의 사회과학《Software Engineering at Google》 (O'Reilly, 무료 공개) — Ch.9 "Code Review" 정독

11핵심 키워드 사전

이 레포에 반복 등장하는 용어 한 자리 정리.

키워드
Code Health (코드 헬스)
이 문서 전체를 지배하는 메타 개념. "지금 이 코드가 좋은가"가 아니라 "이 변경 후에 시스템 전체가 1년 뒤 더 유지보수하기 쉬워지는가"를 묻는다. 헌법 1조의 핵심 단어.
키워드
Continuous Improvement (지속적 개선)
"완벽함"의 반대 개념. 한 번에 perfect를 만들지 말고, 점진적으로 더 나아지는 것을 추구하라는 원칙.
키워드
Over-Engineering (과잉 설계)
현재 필요하지 않은 미래의 일반화·추상화를 미리 짜는 것. 이 문서는 리뷰어가 가장 경계해야 할 패턴 중 하나로 본다. "필요할 때 짜라."
키워드
Every Line (모든 라인)
리뷰어가 사람이 작성한 모든 라인을 봐야 한다는 원칙. 자동 생성/데이터 파일은 스캔해도 되지만, human-written 코드는 한 줄도 건너뛰지 말 것.
키워드
Chesterton's Fence (체스터턴의 울타리)
이 문서가 인용하는 영국 작가 G. K. 체스터턴의 비유. "들판에 울타리가 있고 왜 있는지 모르겠다면, 일단 치우지 말라. 이유를 알아낸 뒤에 결정하라." CL 설명에 "왜"를 적어야 하는 이유의 근거.
키워드
Escalation (에스컬레이션)
리뷰어와 작성자가 합의 못할 때 상위로 의사결정을 넘기는 절차. 팀 토론 → 테크리드 → 코드 오너 → 엔지니어링 매니저 순. 핵심은 "방치하지 않기".
키워드
Self-Contained Change (자기완결적 변경)
"작은 CL"의 정확한 정의. 줄 수가 아니라 "한 가지 일만 하는가"가 기준. 한 PR이 자기 자신만 보고도 의미가 통해야 한다.
TRY IT NOW

오늘부터 30분이면 시작할 수 있는 일

  1. 15분standard.md 한 편만 정독. 그게 사실 이 책의 95%.
  2. 5분 — 내 다음 PR 설명을 "첫 줄=명령문 + 본문=Why"로 다시 쓴다.
  3. 10분 — 다음 리뷰 코멘트부터 Nit: / Optional: / FYI: 라벨을 의식적으로 붙인다. 한 주만 해도 팀이 달라진다.

12참고 링크

TrendShift Deep-Dive · google/eng-practices · 2026.05.27 작성 · 본 문서는 학습 목적의 한국어 정리본이며, 원본 콘텐츠 저작권은 Google (CC-BY 3.0)에 있다.