"이번 주말에 npm 11.16으로 올렸더니 CI가 갑자기 빨갛게 물들었어요. 뭐가 잘못된 거죠?"
📌 핵심 3줄 요약
- npm v12는 2026년 7월 릴리스 예정이며, npm v12 마이그레이션의 핵심은 install 시점 보안 기본값 3종(
allowScripts,--allow-git,--allow-remote)이 모두 거부로 바뀐다는 점이다. - 지금 쓰는 11.16.0 이상에서는 같은 동작이 경고로 미리 노출되므로,
npm install출력의 yellow 경고를 정리해두면 v12 업그레이드 당일에 빌드가 멈추지 않는다. - 모노레포·CI·Docker 이미지 빌드에 영향이 크다. 사전 대응 핵심은
npm approve-scripts로 허용 목록을 만들고package-lock.json에 고정해 두는 것이다.
사내 모노레포를 11.14에서 11.16으로 올리던 지난 금요일, npm ci 끝부분에 처음 보는 노란색 블록이 30줄 가까이 쏟아져 나왔다. esbuild, fsevents, sharp, 내부 사설 레지스트리에서 받아오던 빌드 도구 두 개까지 전부 "install script will be blocked in v12" 경고였다. 처음엔 무시하고 넘어갔는데, 같은 날 다른 팀의 도커 이미지 빌드 파이프라인은 같은 경고가 4,000줄을 넘어 로그 수집기가 5MB 제한에 걸리는 사고가 났다.
v12 정식 릴리스가 한 달 뒤인 7월로 잡혀 있다는 사실을 그때 처음 알았다. 검색해보면 영문 changelog는 짧고 단호한데, 한국어로 정리된 npm v12 마이그레이션 자료가 거의 없어 같은 함정에 빠질 팀이 많아 보였다. 이 글은 그 주말에 정리한 점검 체크리스트, 명령어, 우리 팀이 실제로 박은 함정 세 가지를 다듬어 옮긴 것이다. 9월 이전까지 한 번에 다 끝낼 수 있도록 단계별로 정리했다.
1. v12에서 깨지는 5가지
공식 changelog가 직접 명시한 큰 변경은 install 시점 보안 기본값 3종이지만, 실무에서 함께 영향을 받는 항목까지 묶어 5가지로 정리하면 다음과 같다.
- allowScripts 기본 off — 의존성의
preinstall,install,postinstall스크립트가 자동 실행되지 않는다. 네이티브 빌드(node-gyp)와 git/file/link 소스의prepare도 동일하게 차단된다. - --allow-git 기본 none — git URL 의존성(직접·간접 모두)이 해석되지 않는다. 의존성의
.npmrc가git실행 경로를 덮어쓰는 코드 실행 경로를 막기 위한 결정이다. - --allow-remote 기본 none —
https://...tgz같은 원격 tarball 의존성이 해석되지 않는다. 사설 레지스트리 미러를 URL로 박아둔 프로젝트가 가장 먼저 깨진다. - 스크립트 차단으로 인한 부수 영향 — 네이티브 모듈을 쓰는 패키지(
esbuild,fsevents,sharp,better-sqlite3등)가 prebuilt 바이너리는 받지만 빌드 후 검증·심볼릭 링크 같은 후처리 단계가 빠져 런타임에서 에러가 난다. - 레지스트리 측 staged publishing GA — v12 자체 변경은 아니지만 같은 시기 GA된 staged publishing과 trusted publishing이 사내 릴리스 자동화 스크립트(
npm publish)와 맞닿아 함께 점검해야 한다.
💡 핵심 한 줄
v12에서 새로 추가된 건 없다. 11.16.0 이상에서 이미 같은 검사를 경고로 돌리고 있으므로, "지금 경고를 0으로 만들면 v12 업그레이드는 무사 통과"가 마이그레이션 전략의 전부다.
2. v11→v12 호환성 매트릭스
먼저 v11과 v12에서 같은 명령이 어떻게 다르게 끝나는지 정리한다. 환경별 영향도를 가늠하기 좋다.
| 동작 | npm v11 (현재) | npm v12 (2026-07 예정) |
|---|---|---|
| 의존성 install script | 자동 실행 | 허용 목록 외 차단 |
| git URL 의존성 | 해석·설치 | 에러로 중단 |
| 원격 tarball URL | 해석·설치 | 에러로 중단 |
| npm publish 2FA | 권장 | staged publish + trusted publishing 권장 |
| 경고 누적 시 종료 코드 | 0 (경고만) | 위 3종 위반 시 비0 |
Node.js 런타임 측면에선 v12 자체가 새로운 최소 버전을 요구하지는 않는다. 다만 install script가 막히면서 네이티브 빌드 fallback이 사라지므로, prebuilt 바이너리 제공 범위가 좁은 환경(예: musl 기반 Alpine, ARM64 Linux)에선 Node 런타임을 미리 LTS로 맞춰두는 편이 안전하다.
| Node.js 버전 | npm v12 호환성 | prebuilt 바이너리 커버리지 | 권장도 |
|---|---|---|---|
| Node 18 (Maintenance LTS) | 동작 | 감소 추세 | 전환 권장 |
| Node 20 (Active LTS) | 완전 호환 | 넓음 | 안전 선택 |
| Node 22 (Active LTS) | 완전 호환 | 넓음 | 기본 권장 |
| Node 24 (Current) | 동작 | 중간 | 테스트 환경 한정 |
3. 11.16에서 점검 명령 3개
마이그레이션 첫 단계는 v12를 깔지 말고, 11.16.0 이상에서 같은 검사 결과를 미리 받는 것이다. 다음 3개 명령이면 영향 범위가 모두 파악된다.
세 번째 명령이 핵심이다. npm approve-scripts는 의존성 그래프에서 preinstall/install/postinstall을 정의한 패키지를 골라 대화형으로 허용 여부를 묻는다. 결정 결과는 package.json의 allowScripts 필드에 다음과 같이 기록된다.
버전을 못 박고 싶다면 "esbuild@0.24.2": true처럼 키에 버전을 함께 적을 수 있다. 마이너 업데이트로 스크립트 내용이 바뀌어도 자동으로 허용되지 않게 막는 장치다. 결정 결과는 사람이 읽을 수 있도록 PR로 한 번에 묶어 코드 리뷰 대상에 올리는 편이 안전하다.
4. 모노레포·CI·Docker To-Do
환경별로 실제로 손봐야 하는 지점이 다르다. 우리 팀에선 다음 순서로 진행해 한 주에 끝냈다.
모노레포 (workspaces)
루트 package.json 한 곳에만 allowScripts를 정의하면 모든 워크스페이스에서 공유된다. 워크스페이스별로 흩어두면 중복 리뷰가 발생하니 루트로 모아두는 편이 관리가 쉽다. npm install --workspace=apps/web --dry-run으로 워크스페이스 단위 영향도 확인이 가능하다.
CI (GitHub Actions·GitLab CI)
두 가지를 추가한다. 캐시 키에 npm 버전을 포함해 11.16 이전·이후의 lockfile 결과가 섞이지 않게 하고, npm ci 단계의 stderr를 따로 수집해 install script 경고 누적이 5MB 한도를 넘지 않도록 자른다. NPM_CONFIG_LOGLEVEL=error로 평소엔 조용히 유지하고, 마이그레이션 검증 잡에서만 warn으로 올려 경고를 확인한다.
Docker 이미지
멀티스테이지 빌드에서 빌드 스테이지는 --allow-scripts를 명시적으로 켜고, 런타임 스테이지는 prebuilt artifact만 복사하는 패턴이 안전하다. 다음 한 줄을 추가해 사전 점검한다.
5. publish 보안 업데이트
v12 본체 변경은 아니지만, 같은 분기에 GA된 staged publishing은 라이브러리를 배포하는 팀이라면 함께 정리해두는 편이 좋다. 핵심은 두 가지다.
- staged publishing —
npm stage publish로 등록하면 즉시 공개되지 않고 메인테이너의 2FA 승인 단계를 거친 뒤 공개된다. 잘못된 토큰·잘못된 디렉토리 publish 사고를 막는다. (npm CLI 11.15.0 이상 필요) - trusted publishing — OIDC 기반으로 토큰 없이 publish 한다. GitHub Actions의 OIDC 토큰을 npm registry에 신뢰 등록하면
NPM_TOKEN시크릿을 더 이상 안 쓰게 된다.
사내에선 staged publishing부터 켜는 편이 안전하다. 메인테이너 2FA 승인 단계가 추가될 뿐 기존 워크플로를 거의 그대로 둘 수 있고, trusted publishing은 CI/CD 토큰 회수 정책이 정리된 뒤로 미뤄도 늦지 않다. 두 기능 모두 Node 22.14.0 이상이 권장 환경이다.
⚠️ 단점과 주의할 점
- 네이티브 빌드 의존 프로젝트는 PR이 길어진다 —
allowScripts결정만 30개를 넘는 사례가 흔하다. 보안 리뷰어와 일정 조율이 필요하다. - 사설 레지스트리를 URL로 박아둔 빌드 도구는 별도 마이그레이션이 필요하다.
--allow-remote를 켜는 것보다 사설 레지스트리를 정규 registry로 등록하는 편이 장기적으로 안전하다. - v12 정식 릴리스 직후 1~2주는 사설 패키지의 자체 install script까지 영향을 받는다. 사내 빌드 도구 관리자와 점검 일정을 맞춰두자.
- 이 글의 일정·옵션 동작은 2026-06-10 기준 공식 changelog를 따른 것이고, 7월 RC 단계에서 세부 옵션 이름이 미세 조정될 가능성이 남아 있다.
✅ 핵심 정리
- npm v12 마이그레이션의 본질은 install 시점 보안 기본값 3종(스크립트·git·원격)이 거부로 바뀌는 것뿐이다.
- 11.16.0 이상에서 같은 검사를 경고로 미리 받을 수 있으므로 지금 경고를 0으로 만들면 끝난다.
npm approve-scripts로 허용 목록을 만들고package.json의allowScripts에 고정한다.- publish 쪽은 staged publishing부터 도입하고, trusted publishing은 토큰 정책이 정리된 뒤로 미뤄도 된다.
🚀 지금 바로 할 일
- 로컬에서
npm install --global npm@11.16으로 올리고 사내 가장 큰 리포에서npm ci를 돌려 경고 개수를 메모한다. npm approve-scripts --allow-scripts-pending로 허용 결정을 모아package.json에 반영한 PR을 연다.- CI에
npm ci --allow-scripts=none --allow-git=none --allow-remote=none검증 잡을 1개 추가해 v12 동작을 7월 전까지 매일 확인한다.
- GitHub Changelog — Upcoming breaking changes for npm v12 (2026-06-09)
- GitHub Changelog — Staged publishing and new install-time controls for npm (2026-05-22)
- Andrew Nesbitt — Install-script allowlists 실무 분석
참고 자료
본문에 인용한 1차 공식 자료는 위 링크와 동일합니다. 별도 정리가 필요한 분은 아래를 즐겨찾기에 보관해 두면 v12 GA 시점까지 변경 추적이 수월합니다.
💬 의견
모노레포에서 install script가 가장 많이 걸린 패키지가 무엇이었나요? 어떤 기준으로 허용·차단을 나눴는지 댓글로 공유 부탁드립니다.
작성자: 사내 모노레포(JS·TS 워크스페이스 40여 개)와 도커 기반 CI 파이프라인을 운영하며 npm·pnpm 마이그레이션을 반복해왔습니다. 본문은 2026-06-10 기준 GitHub 공식 changelog와 직접 점검한 명령 결과를 토대로 정리한 1차 자료입니다.
'AI 개발 도구' 카테고리의 다른 글
| Lightricks LTX-2 리뷰: 오픈소스 비디오 생성 모델 직접 돌려본 노트 (2026) (0) | 2026.06.19 |
|---|---|
| 로컬 Qwen vs Claude Opus: 어떤 작업에 어떤 LLM이 낫나 (0) | 2026.06.18 |
| Khoj 완벽 가이드: 자체 호스팅 AI 두뇌 5분 설치 (2026) (0) | 2026.06.08 |
| PP-OCRv5 한국어 PDF OCR 파이썬 사용법 (2026) (0) | 2026.06.07 |
| BitNet.cpp 한국어 설치부터 첫 추론까지 (2026) (0) | 2026.06.07 |