Rolldown, Rust로 다시 쓴 Rollup 알아보기
Rollup은 이미 잘 만들어진 번들러인데, 왜 갑자기 이름이 비슷한 Rolldown이라는 도구가 등장했을까요? 🤔 게다가 Vite는 8 버전부터 오랫동안 써 온 Rollup을 두고 이 Rolldown을 기본 번들러로 채택했습니다. 멀쩡히 돌아가던 도구를 갈아엎은 데는 그만한 이유가 있겠죠.
최근 JavaScript 도구들이 하나둘 Rust로 다시 작성되는 흐름 위에 Rolldown도 놓여 있습니다. SWC가 Babel을, Oxc가 ESLint를 겨냥했다면, Rolldown은 Rollup의 자리를 노립니다. 이번 글에서는 Rolldown이 무엇이고 왜 만들어졌는지, Rollup과 어떻게 호환되는지, 그리고 Vite와는 어떤 관계인지를 직접 번들을 만들어 보며 알아보겠습니다.
Rolldown이란 무엇일까요?
Rolldown은 한마디로 Rust로 다시 작성한 Rollup입니다. Rollup의 API와 플러그인 인터페이스를 거의 그대로 유지하면서, 내부 엔진만 JavaScript에서 Rust로 갈아 끼운 차세대 번들러인데요. Vite와 Vitest를 만든 에반 유(Evan You)가 세운 VoidZero에서 개발하고 있습니다.
VoidZero는 프론트엔드 도구 체인을 통째로 빠른 네이티브 코드로 다시 만드는 것을 목표로 하는 회사로, 2026년 6월 Cloudflare에 인수되었습니다. 인수 후에도 Rolldown을 포함한 도구는 MIT 라이선스 오픈소스로 유지됩니다. 파서와 린터를 담당하는 Oxc, 이들을 하나로 묶은 Vite+가 같은 우산 아래 있고, Rolldown은 그중 번들러 자리를 맡습니다. 즉 Rolldown은 단독 도구라기보다, 통합된 차세대 도구 체인의 한 조각으로 설계되었습니다.
왜 Rolldown을 만들었을까요?
가장 큰 이유는 역시 속도입니다. Rollup은 JavaScript로 작성되어 있어서, 프로젝트가 커지고 모듈 수가 많아지면 번들링 시간이 눈에 띄게 길어집니다. Rust로 다시 쓰면 같은 일을 훨씬 빠르게 처리할 수 있죠.
또 다른 이유는 Vite가 안고 있던 구조적인 고민과 맞닿아 있습니다. Vite는 그동안 개발 서버에서는 esbuild를, 프로덕션 빌드에서는 Rollup을 사용하는 이원 구조였는데요. 이 둘은 동작 방식이 미묘하게 달라서, 개발 환경에서 잘 돌던 코드가 빌드 후에 다르게 동작하는 일이 가끔 생겼습니다. Rolldown은 esbuild만큼 빠르면서 Rollup과 호환되는 단일 번들러를 지향하기 때문에, 개발과 빌드 양쪽을 하나의 도구로 통일할 수 있습니다. 번들러가 하나로 합쳐지면 환경 간 불일치 문제가 근본적으로 사라지는 셈입니다.
그럼 직접 써보겠습니다. 프로젝트를 준비합니다.
mkdir rolldown-demo && cd rolldown-demo
bun add -d rolldown
첫 번들 만들기
Rollup을 써봤다면 거의 그대로라 낯설지 않을 겁니다.
설정 파일도 defineConfig로 감싸는 익숙한 형태인데요.
함수 두 개를 정의하고 그중 하나만 가져다 쓰는 예제로 시작해보겠습니다.
export function add(a, b) {
return a + b;
}
// 아무도 import하지 않는 함수
export function subtract(a, b) {
return a - b;
}
import { add } from "./math.js";
console.log("1 + 2 =", add(1, 2));
import { defineConfig } from "rolldown";
export default defineConfig({
input: "src/main.js",
output: { file: "dist/bundle.js", format: "esm" },
});
-c 옵션으로 설정 파일을 사용해 빌드합니다.
bunx rolldown -c
dist/bundle.js chunk │ size: 0.14 kB
✔ rolldown v1.0.3 Finished in 10.07 ms
10밀리초 만에 끝났습니다. 결과물을 열어 보겠습니다.
//#region src/math.js
function add(a, b) {
return a + b;
}
//#endregion
//#region src/main.js
console.log("1 + 2 =", add(1, 2));
//#endregion
Rollup과 마찬가지로 subtract는 트리 셰이킹으로 제거되었고 add만 남았습니다.
다만 Rolldown은 어느 파일에서 온 코드인지 //#region 주석으로 표시해 주는 점이 조금 다릅니다.
Rollup 플러그인이 그대로 동작합니다
Rolldown의 가장 큰 강점은 Rollup 플러그인 API와 호환된다는 것입니다.
Rollup용으로 작성된 플러그인을 대부분 그대로 쓸 수 있는데요.
Vite 플러그인 만들기에서 다룬 것과 똑같은 형태의 transform 훅 플러그인을 Rolldown에 그대로 넣어 보겠습니다.
import { defineConfig } from "rolldown";
// Rollup, Vite와 완전히 동일한 형태의 플러그인
function versionPlugin(version) {
return {
name: "inject-version",
transform(code) {
if (!code.includes("__APP_VERSION__")) return;
return code.replaceAll("__APP_VERSION__", JSON.stringify(version));
},
};
}
export default defineConfig({
input: "src/main.js",
output: { file: "dist/bundle.js", format: "esm" },
plugins: [versionPlugin("1.0.0")],
});
console.log("버전:", __APP_VERSION__);
빌드해보면 __APP_VERSION__이 정확히 치환됩니다.
//#region src/main.js
console.log("버전:", "1.0.0");
//#endregion
플러그인 코드를 한 글자도 고치지 않았는데 Rollup, Vite, Rolldown 세 도구에서 똑같이 동작합니다. 이것이 Rolldown이 노리는 핵심입니다. 기존 생태계의 자산을 그대로 물려받으면서 엔진만 빠르게 바꾸는 것이죠.
Vite와의 관계
앞서 말했듯 Vite는 8 버전부터 Rolldown을 기본 번들러로 채택했습니다. 실제로 Vite 8을 설치하면 의존성에 Rolldown이 포함되어 있고, 별도 설정 없이도 프로덕션 빌드가 Rolldown으로 처리됩니다.
그 이전 버전을 쓰고 있다면 rolldown-vite라는 패키지로 미리 체험해 볼 수도 있습니다.
이것은 기존 Vite의 Rollup 부분을 Rolldown으로 바꿔 끼운 버전인데요.
package.json에서 vite를 rolldown-vite로 별칭 지정하면 설정을 거의 그대로 둔 채 번들러만 교체해 빌드 속도 차이를 확인할 수 있습니다.
다만 한 가지 기억해 둘 점이 있습니다. Rolldown은 이제 막 1.0대에 들어선 초기 단계의 프로젝트입니다. Rollup과 호환을 목표로 하지만 아직 모든 플러그인과 옵션이 완벽하게 지원되는 것은 아니고, 세부 동작이 계속 다듬어지는 중입니다. 그래서 당장 프로덕션에 적용하기보다, Vite 8을 통해 자연스럽게 쓰거나 사이드 프로젝트에서 먼저 시험해 보는 정도가 적당합니다.
마치며
지금까지 Rolldown이 Rust로 다시 쓴 Rollup이라는 점부터, 왜 만들어졌는지, Rollup 플러그인이 어떻게 그대로 동작하는지, Vite와는 어떤 관계인지까지 살펴봤습니다. 핵심을 정리하면, Rolldown은 Rollup의 친숙한 인터페이스는 그대로 두고 속도만 끌어올린 번들러이고, Vite의 개발과 빌드를 하나로 통일하기 위한 기반이라는 것입니다.
지금 당장 모든 프로젝트를 Rolldown으로 옮길 필요는 없지만, Vite를 쓰고 있다면 어느새 우리 빌드가 Rolldown 위에서 돌아가고 있을 가능성이 높습니다. VoidZero가 그리는 통합 도구 체인이 궁금하다면 Vite+로 도구 통합하기도 함께 읽어 보세요.
더 자세한 설정과 진행 상황은 Rolldown 공식 문서에서 확인할 수 있습니다.
This work is licensed under
CC BY 4.0