다국어 프로젝트에서 번역 파일 관리는 항상 골칫거리입니다. 새로운 기능을 추가할 때마다 기준 언어에 키를 추가하고, 다른 언어 파일에도 동일한 키를 넣어야 하는데 — 이걸 빠뜨리면 런타임에 번역이 표시되지 않는 문제가 발생합니다.
i18n-sync는 이 문제를 해결하는 Claude Code 스킬입니다. 프로젝트의 i18n 구조를 자동으로 감지하고, 누락된 번역 키를 찾아 동기화합니다. 특정 프레임워크에 종속되지 않으며, Next.js, React, Vue, Angular, Rails 등 어떤 프로젝트에서든 동작합니다.
핵심 기능
| 기능 | 설명 |
|---|---|
| 자동 감지 | 프로젝트의 i18n 디렉토리, 프레임워크, 파일 형식을 자동으로 탐지 |
| 구조 인식 | locale_first, domain_first, flat_locale 3가지 패턴 지원 |
| 기준 언어 자동 결정 | 가장 키가 많은 로케일을 기준 언어로 자동 선택 |
| 누락 키 감지 | 기준 언어 대비 다른 언어에서 빠진 키를 정확하게 찾음 |
| 플레이스홀더 동기화 | 누락 키에 [TODO: translate] 마커 자동 추가 |
| 종합 검증 | JSON 구문, 키 일관성, 빈 값, TODO 잔존 확인 |
| 외부 의존성 없음 | Python 표준 라이브러리만 사용 (pyyaml은 YAML 지원 시 선택적) |
지원 프레임워크
package.json, Gemfile, pubspec.yaml 등을 분석하여 프레임워크를 자동으로 감지합니다.
| 프레임워크 | 감지 방법 | 기본 디렉토리 |
|---|---|---|
| next-intl | package.json | messages/ |
| react-i18next | package.json | public/locales/ |
| vue-i18n | package.json | src/locales/ |
| Angular | package.json | src/locale/ |
| Rails | Gemfile | config/locales/ |
| Flutter | pubspec.yaml | lib/l10n/ |
| react-intl / FormatJS | package.json | src/translations/ |
| Generic | 디렉토리 스캔 | locales/, i18n/, lang/ |
지원하는 디렉토리 구조 패턴
프로젝트마다 i18n 파일을 배치하는 방식이 다릅니다. i18n-sync는 3가지 주요 패턴을 모두 자동 인식합니다.
flat_locale — 로케일별 단일 파일
locales/
en.json
ko.json
ja.json
next-intl이나 단순한 프로젝트에서 흔히 사용하는 구조입니다.
locale_first — 로케일 디렉토리 + 네임스페이스 파일
locales/
en/
common.json
auth.json
ko/
common.json
auth.json
react-i18next, vue-i18n 등 네임스페이스 기반 프레임워크의 표준 구조입니다.
domain_first — 도메인 디렉토리 + 로케일 파일
messages/
common/
en.json
ko.json
auth/
en.json
ko.json
기능 도메인 중심으로 번역을 관리하는 커스텀 구조에서 사용됩니다.
동작 원리
두 개의 Python 스크립트가 파이프라인으로 협력합니다.
| 단계 | 스크립트 | 역할 |
|---|---|---|
| 1. 감지 | detect_i18n.py | 프로젝트 스캔 → 프레임워크/구조/로케일/키 수 파악 → JSON 매니페스트 출력 |
| 2. 분석/동기화 | sync_i18n.py | 매니페스트 입력받아 check / sync / validate 중 선택된 모드 실행 |
| 모드 | 동작 |
|---|---|
--check | 누락 키 리포트 (읽기 전용, 파일 변경 없음) |
--sync | 누락 키에 [TODO: translate] 플레이스홀더 추가 |
--validate | JSON 구문, 키 일관성, 빈 값, TODO 잔존 등 종합 검증 |
설치
요구사항: Python 3.10+, Claude Code CLI
# 저장소 클론
git clone <repository-url> /tmp/i18n-sync
# Claude Code 스킬로 등록 (심볼릭 링크)
ln -s /tmp/i18n-sync ~/.claude/skills/i18n-sync
사용법
Claude Code에서 자연어로 사용
Claude Code에서 자연어로 요청하면 스킬이 자동 활성화됩니다:
"번역 동기화해줘"
"i18n 검사해줘"
"누락 번역 확인"
"Check my translation files"
"Sync missing translations"
"Validate i18n files"
CLI 단계별 사용
Step 1: 프로젝트 구조 감지
# 프로젝트 구조 감지
python3 ~/.claude/skills/i18n-sync/scripts/detect_i18n.py . --pretty
# 감지 결과를 파일로 저장 (후속 명령에서 사용)
python3 ~/.claude/skills/i18n-sync/scripts/detect_i18n.py . > /tmp/i18n_config.json
감지 결과 예시:
{
"detected": true,
"framework": "next-intl",
"i18n_root": "messages",
"structure_type": "flat_locale",
"file_format": "json",
"reference_locale": "ko",
"target_locales": ["en", "ja"],
"locales": [
{ "code": "ko", "total_keys": 245, "is_reference": true },
{ "code": "en", "total_keys": 230, "is_reference": false },
{ "code": "ja", "total_keys": 210, "is_reference": false }
],
"summary": {
"total_locales": 3,
"total_reference_keys": 245,
"max_missing_keys": 35,
"needs_sync": true
}
}
Step 2: 누락 키 검사
# 전체 검사 (읽기 전용)
python3 ~/.claude/skills/i18n-sync/scripts/sync_i18n.py \
--config /tmp/i18n_config.json --check --pretty
# 특정 로케일만 검사
python3 ~/.claude/skills/i18n-sync/scripts/sync_i18n.py \
--config /tmp/i18n_config.json --check --locale ja --pretty
Step 3: 동기화 (플레이스홀더 추가)
# 미리보기 (변경 없이 확인만)
python3 ~/.claude/skills/i18n-sync/scripts/sync_i18n.py \
--config /tmp/i18n_config.json --sync --dry-run --pretty
# 실제 동기화 실행
python3 ~/.claude/skills/i18n-sync/scripts/sync_i18n.py \
--config /tmp/i18n_config.json --sync --pretty
Step 4: 종합 검증
python3 ~/.claude/skills/i18n-sync/scripts/sync_i18n.py \
--config /tmp/i18n_config.json --validate --pretty
동기화 전후 예시
기준 언어(ko.json)에 새 키가 추가된 상황:
ko.json (기준)
{
"button": {
"save": "저장",
"cancel": "취소",
"delete": "삭제"
}
}
en.json (동기화 전)
{
"button": {
"save": "Save",
"cancel": "Cancel"
}
}
동기화 실행 후 en.json:
{
"button": {
"save": "Save",
"cancel": "Cancel",
"delete": "[TODO: translate] 삭제"
}
}
동기화 규칙
- 기존 번역은 절대 덮어쓰지 않음
- 누락 키만
[TODO: translate] {기준값}형태로 추가 - 새 키는 기준 파일과 동일한 위치에 삽입 (파일 끝이 아님)
- 대상 파일에만 있는 추가 키는 그대로 보존
레퍼런스
detect_i18n.py 옵션
| 옵션 | 설명 |
|---|---|
[project_dir] | 프로젝트 루트 디렉토리 (기본: 현재 디렉토리) |
--path PATH | i18n 디렉토리 경로 직접 지정 (자동 감지 건너뜀) |
--ref LOCALE | 기준 언어 강제 지정 (예: en, ko) |
--format FORMAT | 파일 형식 강제 지정: json 또는 yaml |
--pretty | JSON 출력 포맷팅 |
sync_i18n.py 옵션
| 옵션 | 설명 |
|---|---|
--config PATH | 감지 결과 JSON 파일 경로 (필수). - 입력 시 stdin |
--check | 누락 키만 리포트 (읽기 전용) |
--sync | 누락 키에 플레이스홀더 추가 |
--validate | 종합 검증 (구문, 키 일관성, 빈 값, TODO, 구조) |
--locale CODE | 특정 로케일만 처리 |
--namespace NAME | 특정 네임스페이스/도메인만 처리 |
--placeholder TEXT | 커스텀 플레이스홀더 (기본: [TODO: translate]) |
--dry-run | 변경 미리보기 (sync 모드 전용) |
--pretty | JSON 출력 포맷팅 |
파이프라인 조합
# 감지 + 검사를 한 줄로
python3 detect_i18n.py . | python3 sync_i18n.py --config - --check --pretty
# 커스텀 플레이스홀더로 동기화
python3 sync_i18n.py --config /tmp/i18n_config.json --sync \
--placeholder "[NEEDS TRANSLATION]" --pretty
# 자동 감지 실패 시 수동 지정
python3 detect_i18n.py . --path config/locales --ref en --format yaml --pretty
마치며
i18n-sync를 만들게 된 직접적인 계기는 특정 프로젝트에 맞춰 하드코딩된 스킬의 한계였습니다. 경로, 기준 언어, 대상 언어가 모두 고정되어 있으면 다른 프로젝트에서 쓰려면 매번 수정해야 합니다. 그래서 처음부터 아무것도 가정하지 않고 — 디렉토리 구조도, 기준 언어도, 프레임워크도 — 모두 프로젝트를 직접 스캔해서 결정하도록 설계했습니다.
결과적으로 next-intl을 쓰는 Next.js 프로젝트든, react-i18next를 쓰는 React 앱이든, Rails의 YAML 파일이든 동일한 명령으로 동작합니다. 기존 번역을 건드리지 않고 누락된 키만 채워넣기 때문에 실수로 번역을 덮어쓸 걱정도 없습니다.
Claude Code 스킬로 등록해두면 “번역 동기화해줘”라는 한 마디로 감지부터 동기화까지 자동으로 처리됩니다. 번역 키 누락을 수동으로 추적하는 데 시간을 쓰고 있다면 한번 써보시기 바랍니다.