본문으로 건너뛰기
피드

JS 번들 뚱뚱해지는 진짜 이유 3가지 - npm 의존성 다이어트 해야 할 때

frontend 약 6분

npm 패키지 트리가 왜 이렇게 무거워졌는지 분석한 글. 레거시 엔진 지원, 원자적 패키지 설계, 오래된 ponyfill 세 가지가 주범임. e18e 커뮤니티가 이 문제를 해결하려고 열심히 삽질 중ㅋㅋ

  • 1

    레거시 엔진 지원·크로스-렐름 처리 등 극소수 요구사항이 전체 생태계 비용으로 전가됨

  • 2

    한 줄짜리 원자적 패키지들이 단일 소비자·중복·공급망 취약점 문제 일으킴

  • 3

    수년 전 이미 네이티브 지원된 기능의 ponyfill이 수천만 다운로드 유지 중

  • 레거시 엔진 지원: IE6급 구형 환경, 글로벌 네임스페이스 보호, 크로스-렐름(cross-realm) 이슈 때문에 is-string 같은 패키지가 생겨남
  • 원자적 아키텍처: path-key, is-wsl, slash 같은 한 줄짜리 패키지들이 남발되면서 의존성 트리가 개복잡해짐
  • Ponyfill 좀비화: globalThis, Array.prototype.indexOf 같이 이미 10년 전에 다 지원된 기능의 ponyfill이 아직도 수천만 다운로드 기록 중 ㄷㄷ
  • 결국 극소수를 위한 설계가 모든 개발자한테 비용을 전가하는 구조가 문제
  • knip, e18e CLI, npmgraph, module-replacements 프로젝트로 지금 당장 의존성 다이어트 가능

1. 레거시 런타임 지원 (크로스-렐름 & 안전성)

is-string, hasown 같은 패키지가 왜 존재하냐면 세 가지 이유가 있음:

① 구형 엔진 지원 Array.prototype.forEach, Object.keys조차 없는 ES3(IE6/7) 환경을 지원해야 하는 사람들이 있음. 뭐... 업그레이드하면 되지 않냐고 하고 싶지만ㅋㅋ

② 글로벌 네임스페이스 보호 Node.js 내부에서 쓰는 "primordials" 개념 - 누군가 Map을 재정의해도 Node 자체가 안 망가지도록 원본 참조를 따로 보관하는 방식. math-intrinsics 같은 패키지가 이 철학으로 만들어짐.

③ 크로스-렐름 값 처리 <iframe>에서 생성된 RegExp는 부모 페이지의 RegExp와 다른 클래스라 instanceof 체크가 실패함. 그래서 Object.prototype.toString.call(val)로 체크하는 패키지들이 생겨남. chai도 이 문제 있다고 함.

진짜 문제: 이런 니즈가 있는 사람은 극소수인데, 그 비용을 우리 모두가 내고 있는 거임 ㄹㅇ.


2. 원자적(Atomic) 아키텍처

"패키지는 최소 단위로 쪼개야 재사용 가능하다"는 철학으로 만들어진 패키지들:

  • arrify - 값을 배열로 변환 (Array.isArray(val) ? val : [val]... 이게 패키지임)
  • slash - 경로의 백슬래시를 /로 교체
  • path-key - 현재 플랫폼의 PATH 환경변수 키 반환 (Unix: PATH, Windows: Path)
  • is-wsl - WSL 환경 체크
  • is-windows - process.platform === 'win32' 체크

왜 문제냐:

  • 단일 소비자 문제: shebang-regexshebang-command에서만, onetimerestore-cursor에서만 씀. 인라인 코드랑 다를 게 없는데 npm 요청, tar 압축 해제, 대역폭 비용은 다 냄
  • 중복 버전 난무: nuxt 의존성 트리만 봐도 is-docker, is-stream, path-key 등이 버전 2개씩 들어있음 ㅋㅋ
  • 공급망 공격 표면 확대: 패키지 많을수록 해킹 포인트도 많아짐. 실제로 이 패키지들 관리자 한 명이 작년에 해킹당해서 수백 개 패키지가 동시에 털렸음 ㄷㄷ

3. 폰어필(Ponyfill)의 좀비화

Ponyfill이란? 환경을 오염시키지 않는 폴리필. import해서 쓰는 방식이라 라이브러리에서 써도 안전함.

문제는 이미 모든 엔진이 기능을 지원하는데도 아무도 제거를 안 했다는 것:

  • globalthis - 2019년부터 전 브라우저 지원, 지금도 주당 4,900만 다운로드
  • indexof - 2010년부터 지원, 주당 230만 다운로드
  • object.entries - 2017년부터 지원, 주당 3,500만 다운로드

그냥 아무도 안 지운 거임. 레전드급 관성ㅋㅋ


그래서 뭘 할 수 있냐

🔧 지금 당장 쓸 수 있는 도구들:

  • knip - 미사용 의존성, 데드코드 탐지
  • e18e CLI - analyze 모드로 대체 가능한 패키지 탐지 + migrate 명령어로 chalk → picocolors 같은 마이그레이션 자동화
  • npmgraph - 의존성 트리 시각화. ESLint의 find-up 브랜치처럼 고립된 비대 의존성 발견 가능
  • module-replacements - 네이티브 대체재나 더 나은 패키지 데이터셋. codemods도 제공

💡 할 수 있는 것:

  • 직접 의존성 보면서 "이게 왜 있지?" 질문하기
  • 불필요해 보이면 maintainer한테 issue 올리기
  • 문제 많은 패키지는 대안 찾기 (module-replacements 참고)

결국 JS 생태계는 '과거의 두려움'이 패키지로 결정화(crystallize)된 것ㅋㅋ 누군가 용감하게 PR 올려서 오래된 ponyfill 지워주는 게 진짜 오픈소스 기여인 시대가 온 듯.

댓글

댓글

댓글을 불러오는 중...

frontend

번은 좋은데, 이제 앤트로픽 품에 있어서 불안하다는 얘기

글쓴이는 번이 빠르고 실용적인 자바스크립트 런타임이라는 점은 인정하지만, 앤트로픽 인수 이후 장기적인 방향을 신뢰하기 어려워졌다고 말한다. 특히 클로드 코드의 품질 저하, 과금 혼란, 서드파티 하네스 제한 사례를 보며 번도 같은 제품 운영 방식에 휘말릴 수 있다고 우려한다.

frontend

왜 터미널 UI가 다시 뜨고 있나

데스크톱 네이티브 UI 툴킷이 플랫폼마다 흔들리고, Electron 앱은 일관성과 키보드 워크플로를 놓치면서 개발자들이 다시 터미널 사용자 인터페이스(TUI)로 돌아가고 있다는 글이다. 저자는 Claude, Codex 같은 명령줄 도구의 성공을 단순한 복고가 아니라, 운영체제 UI 생태계가 제공하지 못한 빠르고 자동화 가능한 인터페이스에 대한 반응으로 본다.

frontend

애플워치 지도 UI 하나에 6년을 갈아 넣은 이야기

Pedometer++ 개발자가 애플워치용 지도 경험을 6년 동안 다듬어 온 과정을 풀어낸 글이다. 서버 렌더링 지도에서 시작해 SwiftUI 기반 커스텀 렌더링 엔진, 전용 베이스맵, Liquid Glass 대응, 최종 UI 구조까지 실제 제품 설계의 시행착오가 꽤 생생하게 담겨 있다.

frontend

애플, Studio Display XDR에 새 색상 기준 Apple CMF 2026 적용

애플이 새 Studio Display와 Studio Display XDR을 내놓으면서 Apple CMF 2026이라는 새 색상 매칭 함수 기준을 같이 공개했음. 단순히 애플식 독자 표준처럼 보이지만, 실제로는 CIE와 협력하고 측정 장비 업체들과도 통합을 추진하는 쪽에 가까움. 테스트 결과 일반 Studio Display는 준수한 P3·sRGB 정확도를 보였고, XDR은 2304개 로컬 디밍 존과 2000니트 HDR을 앞세웠지만 모드별 정확도 차이가 꽤 컸음.

frontend

Figma의 'Sketch 모멘트'가 온다 — Claude Design이 바꾸는 디자인 도구 지형

디자이너 Sam Henri Gold가 Claude Design을 체험한 뒤 디자인 도구의 source of truth가 다시 코드로 이동할 것이라고 주장했다. Figma의 폐쇄적 포맷은 LLM 학습 데이터에서 사실상 제외됐고, agentic 시대에는 HTML/JS 같은 모델이 잘 아는 매체에서 작업하는 Claude Design류가 우위를 가져간다는 예측이다.