Zig의 패키지 매니저가 ‘동작하는 것’과 달리, 프로덕션에서 쓰이기 위해 필요한 도구·서비스·표준 통합이 M×N 형태의 공급망 문제로 확장되는 이유와 이를 완화할 프로토콜 계층의 필요성을 다룬다.
URL: https://nesbitt.io/2026/01/29/zig-and-the-mxn-supply-chain-problem.html
Zig는 2023년 8월 0.11 버전에서 내장 패키지 매니저를 출시했다. 이 패키지 매니저는 매니페스트로 build.zig.zon 파일을 사용하며, 의존성을 URL(대개 GitHub의 tarball)에서 직접 가져온다. 아직 중앙 레지스트리는 없지만, 커뮤니티가 zpm과 aquila 같은 비공식 인덱스를 운영하고 있다.1
패키지 매니저는 작동한다. 의존성을 선언하고, 가져오고, 그 위에서 빌드할 수 있다. 그건 쉬운 부분이다. 어려운 부분은 그 밖의 모든 것, 즉 패키지 매니저를 프로덕션에서 쓸 수 있게 만드는 도구·서비스·인프라의 생태계다.
패키지 관리 지형을 보라. 수십 개의 범주, 수백 개의 도구가 있다. Zig가 npm이나 Cargo와 같은 수준의 도구 지원을 갖추려면, 그 도구들 각각이 Zig 지원을 추가해야 하거나, Zig 커뮤니티가 대안을 만들어야 한다. 엄청난 작업량이다.
어떤 것들은 Zig 커뮤니티만 할 수 있다. 누구도 build.zig.zon 파서를 써주지 않는다. 누구도 해석(리졸루션) 의미론을 알지 못한다. 이런 부분은 언어 전문성이 필요한 영역이다.
매니페스트와 lockfile 파싱. bibliothecary, syft, osv-scalibr 같은 도구는 여러 생태계의 의존성 파일을 파싱한다. 각각에 Zig 파서를 추가해야 한다. 현재 이들 중 build.zig.zon을 지원하는 것은 없다.
취약점 스캐닝. pip-audit, bundler-audit, cargo-audit은 권고(advisory) 데이터베이스와 대조해 의존성을 검사하는 언어별 도구다. Zig에는 zig-audit에 해당하는 도구와, 대조할 권고 데이터베이스가 필요하다.
SBOM 생성. cdxgen과 syft는 프로젝트 파일에서 SBOM을 생성한다. SBOM(자재 명세서)에 Zig 패키지를 포함하려면 Zig의 의존성 형식을 이해해야 한다.
의존성 트리 시각화. Cargo에는 cargo tree가 있고, npm에는 npm ls가 있다. Zig에도 해석된 의존성 그래프를 보여주는 동등한 도구가 필요하다.
레지스트리 소프트웨어. Zig가 중앙 레지스트리를 원한다면, 누군가 그것을 만들고 운영해야 한다. Crates.io, RubyGems.org, PyPI는 모두 상당한 엔지니어링 노력이 필요했다. 비공식 인덱스는 존재하지만 권위(authoritative)가 없다.
PURL 및 VERS 타입. Package URL 스펙과 버전 범위 스펙은 표준이지만, 본질적으로 더 높은 수준의 추상화라기보다는 기존 생태계를 매핑한 것이다. 새로운 패키지 매니저가 생길 때마다 타입을 제안하고, 의미론을 문서화하고, PR을 병합받아야 한다. Zig는 2023년부터 보류 중인 제안이 있다. PURL 타입이 없으면 Zig 패키지는 SBOM, 권고 데이터베이스, 교차 생태계 도구에서 표준화된 방식으로 참조될 수 없다.
다른 통합은 Zig에 아직 관심이 없을 수도 있는 회사들의 동의가 필요하다. 여기서는 시장 점유율이 중요하다. 다음에 무엇을 지원할지 우선순위를 정하는 SaaS 벤더 입장에서 Zig는 더 큰 사용자 기반을 가진 언어들과 경쟁한다. Zig 커뮤니티가 모든 것을 제대로 해도, Dependabot, Renovate, Snyk가 관심을 가질 때까지 기다려야 한다. 도구 없이는 채택이 어렵고, 채택 없이는 도구가 생기지 않는다.
의존성 업데이트 도구. Dependabot은 고정된 생태계 집합만 지원한다. 새로운 생태계를 추가하려면 GitHub의 엔지니어링 시간이 필요하다. Renovate는 더 확장 가능하지만 여전히 매니저 플러그인이 필요하다. 둘 다 현재 Zig를 지원하지 않는다. 2023년의 Dependabot 이슈와 Renovate 논의가 있으나 둘 다 멈춰 있다.
취약점 데이터베이스. GitHub Advisory Database와 OSV에는 Zig의 식별자 체계를 사용해 Zig 패키지에 대한 권고가 등록되어야 한다. 이를 위해 Zig 패키지를 어떻게 식별할지 합의해야 하며(PURL에는 zig 타입 제안이 있지만 아직 병합되지 않았다).
SCA 도구. Snyk, Socket, Sonatype 등은 Zig 지원을 추가해야 한다. 각 벤더는 무엇을 지원할 가치가 있는지 독립적으로 판단한다.
엔터프라이즈 아티팩트 저장소. JFrog Artifactory와 Sonatype Nexus는 많은 생태계에 대해 패키지 프록시 및 호스팅을 지원한다. Zig는 목록에 없다.
메타데이터 플랫폼. deps.dev, Libraries.io, ecosyste.ms는 생태계 전반의 패키지 데이터를 집계한다. 각 플랫폼은 Zig의 패키지 형식을 이해하고, 패키지가 게시되는 곳에서 Zig 패키지를 인덱싱해야 한다.
포지(Forge) 통합. GitHub의 의존성 그래프, GitLab의 의존성 스캐닝, Gitea의 보안 기능은 UI에서 Zig 의존성을 보여주려면 Zig 매니페스트를 파싱해야 한다.
SBOM 포맷. CycloneDX와 SPDX는 생태계별 가이던스를 갖고 있다. Zig도 둘 모두에서 표현이 필요하다.
신뢰 기반 퍼블리싱(Trusted publishing). PyPI의 Trusted Publishers와 npm의 provenance는 Sigstore와 레지스트리별 OIDC 플로우에 의존한다. Zig에 중앙 레지스트리가 생긴다면, 동일한 인프라도 필요하다.
전형적인 경로는 이렇다:
이 과정은 수년이 걸린다. Go 모듈은 2018년에 출시되었지만 여전히 오래된 생태계만큼 완전한 도구 동등성(tooling parity)을 갖추지 못했다. Rust는 2015년부터 존재했고 Cargo는 지금은 잘 지원되지만, 그것도 10년에 걸친 점진적 통합의 결과다.
그 과정 어딘가에서 패키지 매니저 설계자들은 초기 결정 중 일부가 통합을 더 어렵게 만든다는 것을 깨닫는다. 패키지에 고유 식별자를 부여하지 않았을 수도 있다. 버전 스킴이 PURL에 깔끔하게 매핑되지 않을 수도 있다. 레지스트리 대신 URL에서 의존성을 가져오면 SBOM 도구 곳곳에 박혀 있는 가정을 깨뜨릴 수도 있다. 하지만 그때쯤이면 사용자들은 현재 동작에 의존하고 있다. 출시 후 패키지 매니저를 바꾸는 건, 타이타닉을 찾으러 가는 잠수함이 항해 중에 선체를 바꾸는 것과 같다.
새 패키지 매니저는 모두 같은 루프를 돈다. 각 도구 벤더는 같은 패턴을 반복 구현한다: 매니페스트 파싱, 의존성 추출, 권고와 대조. 이 작업은 생태계 전반에서 수십 번 중복되며, 각 구현은 엣지 케이스에 대해 조금씩 다른 결정을 내린다.
엔지니어링을 넘어 인간적 조율도 필요하다. 우선순위가 다른 자원봉사자들이 관리하는 저장소에 PR을 통과시키는 일, 드문드문 모이는 위원회가 PURL 제안을 검토하도록 하는 일, 다음 차례의 생태계보다 당신의 생태계를 우선순위로 삼도록 SCA 벤더를 설득하는 일. Zig의 PURL 제안은 2023년부터 열려 있다. 이건 기술 문제가 아니다. 이는 패키지 관리가 난제(wicked problem)인 이유의 일부다. 이해관계자가 너무 많고, 단일 권위가 없으며, 해결책이 또 다른 문제를 만들어낸다.
패키지 관리는 아직 LSP 이전 시대에 있다. Language Server Protocol 이전에는 모든 IDE가 모든 언어 지원을 구현해야 했다: M개의 에디터 × N개의 언어 = M×N개의 통합. LSP는 이를 M+N으로 바꿨다. 각 에디터는 프로토콜을 한 번 구현하고, 각 언어는 서버를 한 번 구현하면, 모두가 함께 동작한다.
패키지 관리도 같은 M×N 문제를 갖고 있다. 모든 도구(Dependabot, Snyk, Syft, deps.dev)가 모든 생태계(npm, PyPI, Cargo, Go)에 대한 지원을 따로 구현한다. 각 통합은 맞춤형이다. Zig가 등장하면 모든 큐의 맨 뒤로 밀린다.
모든 코드베이스는 의존성 그래프다. 문법은 다르고, 해석 알고리즘도 다르며, 레지스트리는 서로 다른 API를 갖지만, 구조는 같다: 노드는 패키지, 엣지는 버전 제약, 목표는 일관된 구체 버전 집합이다. 표면적 차이를 걷어내면 Zig의 그래프는 Cargo의 그래프와, npm의 그래프와 닮아 있다.
우리는 의존성 생명주기 프로토콜(Dependency Lifecycle Protocol, DLP), 즉 패키지 관리 세계의 LSP가 필요하다. A Protocol for Package Management에서 나는 이것이 어떤 모습일 수 있는지(매니페스트 구조, 해석 동작, 레지스트리 API에 대한 공통 정의) 스케치했다. 만약 그것이 존재한다면, 새로운 패키지 매니저는 그에 맞춰 구현할 수 있다. 프로토콜을 말하는 도구들은 SCA 벤더가 각각 별도로 Zig 지원을 추가하지 않아도 Zig 지원을 얻게 될 것이다.
디지털 주권에서의 의존성 계층은 다른 각도에서 비슷한 주장을 한다: 의존성은 국가와 기관이 통제하지 못하는 병목지점이다. Zig 문제와 주권 문제는 같은 문제다. 하나는 “새 언어 생태계는 왜 빠르게 부트스트랩할 수 없는가”이고, 다른 하나는 “기관은 왜 자체 의존성 인프라를 통제할 수 없는가”다. 둘 다 대체(substitution)를 가능하게 하는 추상화 계층의 부재를 가리킨다.
프로토콜의 부재는 기본적으로 락인(lock-in)을 만든다. 악의적이어서가 아니라, 중력처럼 당겨서 그렇다. Zig라면 Dependabot, Snyk, GitHub의 의존성 그래프가 필요하다. 유럽의 기관이라면, 취약점 데이터가 거기에 있기 때문에 같은 도구들이 필요하다. 프로토콜이 있다면 의존성 계층은 경쟁 가능(contestable)해진다. 다른 것들과 연합(federate)하는 자체 레지스트리를 운영할 수도 있다. 같은 언어를 말하는 지역 취약점 데이터베이스를 세울 수도 있다. 미국의 세 회사가 통제하지 않는 도구를 사용할 수도 있다.
정부는 이미 조달을 위해 접근성, 보안 인증, 데이터 레지던시 같은 표준을 의무화한다. 만약 미 연방정부나 EU의 조달이 공통 프로토콜을 구현한 의존성 도구를 요구한다면, 인센티브 구조는 뒤집힌다. 정부 조달은 블록 단위로 움직이는 거대한 시장이다. 프로토콜 준수 없이는 정부에 팔 수 없다면, 모든 벤더는 하룻밤 사이에 그 예산을 찾게 된다. Zig 지원은 부수 효과로 따라온다: Snyk가 정부에 계속 판매하기 위해 프로토콜을 구현한다면, Zig는 같은 스펙을 따름으로써 커버리지를 얻는다.
Cyber Resilience Act는 이미 SBOM 요구사항으로 이 방향을 밀고 있다. PURL, OSV, CycloneDX는 표준을 향한 시도지만, 규범적(prescriptive)이라기보다는 기술적(descriptive)이다. 존재하는 것을 정의하기보다는 존재하는 것을 문서화한다. CRA는 산출물을 의무화하지만, 그 산출물이 생태계 전반에서 의미를 갖게 해줄 상호운용 계층은 의무화하지 않는다.
지금은 새 패키지 매니저를 출시하는 비용에, 주변 인프라 전체를 다시 구축하는 비용이 포함된다. 언어들은 통합 부담이 너무 커서, 딱 맞지는 않아도 기존 도구에 머무른다. Zig가 지금 그 과정을 겪고 있다. Rust보다 완만한 학습 곡선으로 메모리 안전성을 탐구하는 연구 언어 Rue는 아직 패키지 매니저가 없다. 언젠가 생기면, 같은 통합 고행을 겪게 될 것이다. 프로토콜 계층이 존재하기 전까지는, 모든 새 언어가 그럴 것이다.