새로운 패키지 매니저가 나왔다!? (Bun 대안)

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

Transcript

00:00:00이것은 Node를 대체하는 대신 그 위에서 동작하는 올인원 JavaScript 툴킷, Nub입니다.
00:00:04현재 여러분이 사용 중인 모든 도구를 대체할 수 있죠. pnpm보다
00:00:085배 빠른 패키지 매니저부터 TSX를 대체 가능한 TypeScript 러너,
00:00:13심지어 Node 버전 매니저까지 말이죠. Bun의 핵심 기능들을 표준 Node.js 위로 가져왔습니다.
00:00:17아마도 이것이 Nub이 Bun의 철자를 거꾸로 뒤집은 이유일 겁니다.
00:00:21JavaScript 개발자들이 바퀴의 재발명을 좋아하긴 하지만, 이건 듣보잡 프로젝트가 아닙니다.
00:00:25Zod의 제작자이자 tRPC의 PoC를 만들고
00:00:29Bun에서도 일했던 Colin이 만들었죠. 그럼 곧바로 하나씩 살펴보겠습니다.
00:00:38Nub은 단 하나의 Rust 바이너리 파일이며 Mac, Windows, Linux를 모두 지원합니다. 인트로에서 보여드렸듯
00:00:44이것들은 대체 가능한 도구 중 일부일 뿐입니다. 파일 러너, 스크립트 러너,
00:00:47패키지 러너, 패키지 매니저, 그리고 Node 버전 매니저 역할까지 수행하죠. 하나씩 살펴볼까요?
00:00:52먼저 파일 러너입니다. 이 하나만으로도 수많은 기능을 제공하는데요. 파일 러너는 단순
00:00:56타입 제거(Type Stripping) 수준인 Node와 달리 풀 TypeScript를 지원하여 TSX나 ts-node를 대체할 수 있습니다.
00:01:02여기 enum과 namespace, 매개변수 속성(param properties)이
00:01:06포함된 TypeScript 파일이 있습니다. 원래 Node에서는 실행할 수 없는 구문이죠. 하지만 Nub으로
00:01:11해당 파일을 실행해보면, Node에서 실패했던 것과 달리 아주 잘 실행되는 것을 볼 수 있습니다.
00:01:15여기서 Nub 대신 Node를 사용해보면, 지원되지 않는 TypeScript 구문이라는 에러가 발생합니다.
00:01:20namespace나 enum을 인식하지 못하기 때문이죠. 또한 파일 러너는 dotenv 같은 도구를 대체하여
00:01:24환경 변수를 자동으로 로드해 줍니다. .env, .env.local 및
00:01:29Node 환경 전용 파일까지 지원하며, 자동 변수 확장 기능도 갖추고 있습니다. 아래를 보면
00:01:33다른 환경 변수들로 조합된 변수가 있습니다. 데이터베이스 사용자 및
00:01:37데이터베이스 호스트 정보가 있죠. 이제 Nub으로 이 파일을 실행하면, 환경 변수들을
00:01:41자동으로 불러와 다른 환경 변수 값들을 조합한 헬스 체크 URL을 생성해 줍니다.
00:01:46그리고 제 API 키가 여기 .env에 있는 값과 실제로 일치하지 않는 것을 볼 수 있는데요.
00:01:50.env.local이 항상 우선순위를 갖기 때문입니다. 여기서는 API 키가
00:01:54Better Stack 구독으로 설정되어 있네요. AI 및 개발자 최신 소식을 계속 받아보고 싶다면
00:01:58꼭 해두셔야 할 설정입니다. 구독 부탁드립니다, 큰 힘이 됩니다. 이어서 계속 진행하여
00:02:02nub src/index.tsx를 실행해보면, 모든 것이 정상 작동하는 것을 확인할 수 있습니다.
00:02:07저의 Nub 종합 예제 파일인데요. 이 파일의 코드에는 Nub 파일 러너가 제공하는 수많은 기능이 사용되었습니다.
00:02:12가장 먼저, JSON 파일뿐만 아니라 YAML,
00:02:15HTML, 텍스트 파일까지 직접 import할 수 있으며, tsconfig-paths 같은 도구도 대체합니다. tsconfig에
00:02:20@config 경로 별칭을 설정해두면, Node가 알아서 올바르게
00:02:24해당 경로를 찾아 해석해 줍니다. 또한 여기 service나 sealed 같은 데코레이터도 지원하죠.
00:02:29JSX 지원이 포함되어 있어 tsconfig 설정에 따라 트랜스파일해 주며,
00:02:34명시적 자원 관리를 위한 using 키워드 같은 최신 최신 키워드도 사용할 수 있습니다. 그뿐만 아니라
00:02:38Web Workers, Temporal 등 수많은 최신 API를 지원합니다. 이를 지원하지 않는
00:02:43Node 버전에서는 폴리필을 자동으로 적용해 주며, LocalStorage 지원 같은 실험적
00:02:48Node 기능의 플래그도 자동으로 해제해 줍니다. 이건 파일 러너가 지원하는 전체 기능 중
00:02:52극히 일부일 뿐인데요. 특히 Node의 옵션 플래그들과 완전히 호환된다는 점을 강조하고 싶습니다.
00:02:56어차피 결국 Node를 실행하는 것이기 때문에 해당 플래그들을 그대로 전달할 뿐이죠. 즉,
00:03:01스크립트에 Node가 지원하지 않는 기능이 전혀 없다면, Nub 대신 Node로 바꿔도 정확히
00:03:06동일한 결과를 얻을 수 있습니다. 참고로 이 모든 작업은 속도 오버헤드가 거의 없이 실행됩니다.
00:03:10Node에 최대한 가까운 성능을 내야 하며, 문서에 따르면 Nub 파일 실행에 걸리는 시간은
00:03:14Node와 완전히 동일하다고 합니다. 물론 Bun보다 빠르진 않다는 점은 인정해야겠네요. Bun은 Node를
00:03:19대체하는 네이티브 런타임이고, Nub은 Node 위에서 작동하니까요. 그래서 어떤 게 더 빠른지 알아보기 위해
00:03:24제 Mac에서 직접 벤치마크를 돌려보았습니다. 보기 좋게 정리해서
00:03:28확인해 보니, 제 환경에서는 Node가 실제로 가장 빨랐습니다. Nub과 정확히 동일한
00:03:31속도는 아니었고 Nub이 약간 뒤처졌지만, TSX는 둘 모두보다 느렸습니다. 다음으로
00:03:36파일 러너를 넘어, 두 번째 핵심 기능인 Node 버전 매니저를 보겠습니다. 이제 nvm이나
00:03:41fnm이 필요한 시대는 지났습니다. Nub 환경에서는 프로젝트에 .node-version 파일이 있거나 .nvmrc,
00:03:46혹은 package.json에 명시되어 있다면, Nub이 Node.js 공식 사이트에서 필요한 버전을 자동 설치해 줍니다.
00:03:52현재 이 프로젝트는 최신 Node 26 버전을 사용 중인데요, 이 파일의 내용을 24 같은
00:03:56다른 버전으로 변경하고 Nub으로 다시 실행하면, 알아서 해당 Node 버전을 가져옵니다.
00:04:02또한 기대하시는 일반적인 버전 관리 명령어도 모두 갖추고 있습니다. Node 버전을 설치하거나, 설치된
00:04:06버전 목록을 확인하고, 삭제할 수도 있으며, 해당 Node 버전 파일을 작성해 주는
00:04:10버전 고정(pinning) 기능도 지원합니다. 정말 이렇게 간단하죠. 그럼 다음 세 가지 기능으로
00:04:15넘어가 보겠습니다. 바로 Nub이 pnpm과 Bun을 대체할 수 있는 영역입니다.
00:04:20첫 번째는 세 번째 기능인 패키지 매니저입니다. pnpm보다 5배 빠르다고 장담하는데,
00:04:25pnpm도 이미 엄청나게 빠르다고 생각했거든요. 예상대로 잘 동작하며, `nub install`로 패키지를 설치합니다. 한 가지
00:04:31매우 멋진 점은 기존 락파일을 그대로 계승할 수 있다는 것인데요. 프로젝트에서 이전에 Bun이나 pnpm을 사용했다면
00:04:36Nub은 자체 락파일을 만드는 대신 해당 락파일을 업데이트합니다. 이 덕분에 필요한 경우
00:04:41도구 간 전환이 매우 쉽고, pnpm과의 호환성도 마찬가지입니다. Nub의 모든 패키지
00:04:46관리 명령어는 워크스페이스 카탈로그 같은 pnpm의 고급 기능을 포함해
00:04:51pnpm과 완전히 동일합니다. 옵션 플래그도 똑같아서 pnpm과 Nub을 바로 교체해 쓸 수 있고,
00:04:57npm, Bun, Yarn을 사용 중이더라도 해당 패키지 매니저의 설정 옵션들을 자동으로 인식합니다.
00:05:02속도에 대한 주장에 대해 이야기해 보자면, 벤치마크 결과 Nub은 캐시가 있는 상태에서의
00:05:06동결 설치(warm frozen install) 기준 가장 빨랐으며, 1,168개 패키지를 설치하는 데 346밀리초가 걸렸습니다. 제 기기에서도
00:05:13212개의 고유 패키지로 해석되는 14개의 의존성을 설치해보는 테스트를 진행했는데요, 벤치마크 결과 Nub이
00:05:19가장 빠르다는 것이 증명되었습니다. Nub은 136밀리초 만에 패키지를 설치했고, Bun이 239밀리초로 2위,
00:05:25그리고 pnpm과 npm은 1초 이상 걸렸습니다. 제 컴퓨터에서 입증된
00:05:30속도 주장은 정말 놀라운 수준입니다. 또한 이 패키지 매니저는 보안 측면에서도
00:05:35pnpm의 장점을 가져왔는데요. 기본적으로 최소 출시 경과 시간을 24시간으로 설정하며, 승인되지 않은
00:05:40빌드 스크립트는 실행하지 않으므로, 대부분의 공급망 공격(Shai Hulud)으로부터 안전합니다. 패키지 매니저의
00:05:45다음 핵심 요소는 패키지 실행 기능인 4번째 기능입니다. 핵심은
00:05:49npx보다 19배 빠르다는 점인데요. `nub x` 명령어는 node_modules 안의 바이너리 폴더를 직접
00:05:54찾아내어 Rust 단에서 바이너리를 직접 실행합니다. 래퍼에 Node 프로세스가 끼어들지
00:05:59않는다는 뜻이죠. 즉, node_modules에 직접 접근하기에 어떤 패키지 매니저와도 잘 동작합니다.
00:06:03대부분의 Nub 명령어와 마찬가지로, dlx 명령어를 포함해 `pnpm exec`와
00:06:07옵션 플래그까지 완전 호환됩니다. 제 Mac에서 벤치마크를 돌려보니, esbuild 실행 시 pnpm이
00:06:12423밀리초 걸린 것에 비해 Nub은 169밀리초로 가장 빠르고 확실한 성능을 보여주었습니다.
00:06:20패키지 매니저에 필요한 마지막 기능은 스크립트 러너인데요, `pnpm run`보다
00:06:2424배 빠르고 라이프사이클 훅, npm 환경 변수,
00:06:29그리고 인자 전달(argument forwarding)을 지원합니다. npm이나 pnpm을 쓸 때는 Node.js 프로그램을
00:06:34구동하여 매번 각 패키지 매니저의 JavaScript를 로드하지만, Nub은 시작 프로세스 없이
00:06:38Rust 바이너리를 곧바로 사용합니다. 로컬 벤치마크 결과 역시 `nub run`이 제일 빨랐지만,
00:06:43공식 문서에서 제시한 격차만큼 크지는 않았습니다. 그리고 이 영상에서 네 번째 말씀드리는데,
00:06:47이 명령어 역시 pnpm과 플래그 단위까지 완전 호환되며,
00:06:51pnpm의 모노레포 기능도 동일하게 지원합니다. 마지막 세 기능에 대해 한 가지 짚고 넘어갈 점은,
00:06:56Nub이 바퀴를 재발명한 것이 아니라는 사실입니다. 내부적으로 Mise의 제작자인
00:07:00jdx가 만든 패키지 매니저인 owb를 사용합니다.
00:07:04그가 다른 라이브러리에 임베드할 수 있게 만든 패키지 매니저를, Colin이 협력하여
00:07:08Nub에 활용한 것이죠. 무단 도용이 아닙니다. 여기까지가 Nub의 주요 핵심 기능들이며,
00:07:13공식 setup-node 액션을 직접 대체하는 GitHub Actions
00:07:17드롭인 대체재 등 더 살펴볼 기능들이 아주 많습니다. Node 주변의 제반 작업을
00:07:21훨씬 쉽게 만들고자 제작되었죠. 여기서 질문입니다. “내가 실제로 이걸 쓸까?”
00:07:26제 답변은 특정 상황이라면 “YES”입니다. 솔직히 저는 Bun을
00:07:31주로 사용하고, 개발하면서 딱히 호환성 문제를 겪은 적이 없습니다. 혹시 모르죠,
00:07:35새로운 Rust 포트로 이탈할 수는 있겠지만, 그 경우에도 다른 작업엔 pnpm을 쓸 것이고,
00:07:40pnpm이 너무 느리다고 느낀 적도 솔직히 없습니다. 또한 Node 버전 관리는 Mise를 쓰기 때문에
00:07:44그쪽 기능이 당장 필요하진 않지만, TSX를 대체하는
00:07:48파일 러너 기능만큼은 탐납니다. 그렇지만 제가 보는 최고 유스케이스는
00:07:52일회성 가상 머신(VM)을 새로 띄울 때입니다. 테스트를 위해 빠르게 가상 머신을 띄울 때가 있는데,
00:07:57Node 환경을 즉시 구축하고 싶다면 Nub이야말로 가장 완벽한 종합 패키지이자
00:08:01가장 빠르고 쉬운 방법이라고 생각합니다. 단지 익숙한 기존 습관 때문에
00:08:05Nub을 매일 쓰지 않을 뿐이죠. 여러분은 어떤 패키지 매니저를 쓰시나요?
00:08:08Rust로 재작성된 Nub을 보고 Bun에서 갈아타려는 생각을 하셨을까요?
00:08:12아래 댓글로 공유해 주세요. 구독 버튼도 부탁드리며,
00:08:16언제나 그렇듯 다음 영상에서 뵙겠습니다.

Key Takeaway

Nub은 Node.js 런타임 환경을 유지하면서 pnpm 대비 최대 5배 빠른 패키지 관리와 풀 TypeScript 실행, 자동 버전 관리를 하나로 통합한 Rust 기반 올인원 툴킷이다.

Highlights

  • Nub은 Rust 기반 단일 바이너리로 구현한 올인원 JavaScript 툴킷이며, Node.js 위에서 실행 동작한다.

  • pnpm보다 fast-path 설치 기준 속도가 높으며, 212개 패키지 테스트 기준 136ms만에 설치를 완료해 Bun(239ms)과 pnpm(1s+)을 앞선다.

  • Node.js 표준과 달리 TypeScript의 enum, namespace, parameter properties 및 JSX 구문을 별도 빌드 단계 없이 바로 execution을 지원한다.

  • npx보다 19배 빠른 패키지 실행을 목표로 삼으며, node_modules 내 바이너리를 Rust 레벨에서 Node process wrapper 없이 직접 구동한다.

  • pnpm의 락파일, 옵션 플래그, workspace catalog와 100% 호환성을 유지하여 기존 워크플로우 변경 없이 대체 가능하다.

Timeline

Nub의 정체성과 주요 개발 배경

  • Nub은 Node.js를 대체하는 대신 표준 Node.js 위에서 동작하는 올인원 JavaScript 툴킷이다.
  • Zod 제작자이자 tRPC PoC 개발자, 전 Bun 엔지니어인 Colin이 개발을 주도했다.

Bun의 핵심 기능을 표준 Node.js 스택으로 가져오는 것을 목표로 설계되었다. 도구의 명칭인 Nub은 Bun의 철자를 역순으로 배열한 것이다. 독자적인 ecosystem을 강제하는 대신 기존 Node.js ecosystem과의 완벽한 호환성을 지향한다.

TypeScript 통합 실행 및 파일 러너 성능

  • TSX나 ts-node 없이 enum, namespace, parameter properties 등 풀 TypeScript 구문을 직접 실행한다.
  • .env.local 우선순위 처리 및 환경 변수 자동 확장, JSON·YAML·HTML 파일의 direct import를 지원한다.
  • 기존 Node.js 실행 대비 런타임 성능 오버헤드가 거의 발생하지 않는다.

단순 구문 제거(Type Stripping) 방식의 Node.js 내부 실행과 달리 TSX 수준의 완전한 TypeScript 구문 해석을 제공한다. tsconfig-paths 호환 경로 별칭, Decorator 지원, Web Workers 및 Temporal 폴리필 적용까지 파일 러너 내부에서 자동으로 처리한다. Apple Silicon Mac 기준 벤치마크 테스트 결과 TSX보다 빠른 실행 속도를 보여준다.

자동화된 Node.js 버전 관리 시스템

  • nvm이나 fnm 등의 독립적인 버전 관리 도구를 대체한다.
  • .node-version, .nvmrc, package.json 파일을 감지하여 필요한 Node.js 버전을 자동 다운로드한다.

프로젝트 진입 시 명시된 Node.js 버전을 공식 소스에서 자동으로 감지해 가져온다. 버전 설치, 목록 조회, 삭제, 버전을 고정하는 pin 기능까지 단일 명령어 체계 안에서 수행한다.

초고속 패키지 매니저 및 보안 메커니즘

  • 136ms만에 212개 패키지 의존성 해석 및 설치를 완료하여 Bun과 pnpm보다 높은 처리 속도를 보여준다.
  • pnpm 및 Bun의 기존 락파일을 직접 업데이트하여 도구 전환 부담을 없앴다.
  • 패키지 최소 출시 경과 시간 24시간 제한과 무단 빌드 스크립트 차단으로 공급망 공격을 예방한다.

pnpm의 워크스페이스 카탈로그 기능 및 옵션 플래그와 100% 호환된다. 캐시 기반 frozen install 테스트 기준 1,168개 패키지를 346ms만에 처리한다. 보안 정책 면에서는 Shai Hulud 유형의 공급망 공격 차단용 기본 방어 설정이 적용되어 있다.

Rust 바이너리 기반의 패키지 및 스크립트 실행기

  • node_modules 내 바이너리를 Rust 차원에서 래퍼 프로세스 없이 즉시 실행한다.
  • Mise 개발자가 만든 패키지 매니저 owb를 코어 엔진으로 활용한다.
  • 일회성 가상 머신(VM) 환경 구축 및 CI/CD 파이프라인 단축에 유용하다.

esbuild 실행 벤치마크 기준 pnpm이 423ms 소요된 반면 Nub은 169ms를 기록했다. JavaScript 런타임 구동 오버헤드가 없기 때문에 `nub run` 및 `nub x` 명령어 실행 시 시작 지연이 줄어든다. 단일 바이너리 특성 덕분에 가상 머신 환경이나 GitHub Actions CI 구성(`setup-node` 대체)을 단순화하는 데 활용 가치가 높다.

Community Posts

View all posts