Skip to content
Published on

JS 빌드 도구 Rust 물결 2026 — Turbopack / Rspack / Rolldown / oxc / Biome / Vite 6 / Bun 심층 비교

Authors

프롤로그 — "왜 또 빌드 도구냐"

2010년대 후반 프론트엔드를 했다면 한 번쯤 들어본 농담이 있다. "JavaScript 빌드 도구는 6개월마다 바뀐다." Grunt, Gulp, Browserify, webpack, Parcel, Rollup, Snowpack, esbuild, Vite, Turbopack… 농담은 진실이었다.

그런데 2024~2026년의 흐름은 종류가 다르다. 새 도구가 아니라 새 언어로 다시 짠 도구가 줄지어 등장하고 있다. 거의 전부 Rust다 (esbuild만 Go, Bun만 Zig). webpack은 JS로 짠 번들러였고, Babel은 JS로 짠 트랜스파일러였으며, Prettier와 ESLint는 JS로 짠 도구였다. 2026년 같은 자리를 노리는 후계자들은 모두 네이티브 언어로 컴파일된다.

이건 세대교체다. 단순히 "더 빠른 도구가 나왔다"가 아니라 언어와 아키텍처가 통째로 갈리는 중이다.

이 글은 그 지형을 정리한다. 어떤 도구가 어떤 역할이고, 누가 만들고, 어디에 쓰이며, 2026년 현재 어느 단계에 있고, 무엇을 골라야 하는지. 단순한 벤치마크 모음이 아니라, 빌드 체인 전체의 구조를 그린다.


1장 · 왜 지금 Rust 물결인가

JavaScript 도구가 JavaScript로 쓰인 건 자연스러웠다. 사용자가 JS 개발자고, 컨트리뷰터가 JS 개발자고, 생태계가 JS였다. webpack, Rollup, Babel, Prettier, ESLint — 전부 JS다.

문제는 규모다. 2010년대 후반부터 다음 세 가지가 동시에 일어났다.

  1. 앱이 커졌다. 5만 모듈짜리 모노레포가 평범해졌다. 한 번 빌드에 5분, dev 서버 시작에 30초.
  2. CI/CD가 일상이 됐다. 매 PR마다 빌드/테스트/린트가 도는데, 단일 스레드 JS 도구는 병목이다.
  3. 타이트한 피드백 루프 의존도가 올라갔다. HMR이 1초 걸리는 vs 100ms 걸리는 — 하루 종일 개발하는 사람에게는 인지적으로 다른 도구다.

JS는 본질적으로 싱글 스레드 + GC + 동적 타입이다. 파서·AST 변환·번들링은 CPU-바운드 병렬 작업의 정수다. Rust는 그 반대다 — 멀티 스레드, GC 없음, 정적 타입, zero-cost abstraction. 트레이드오프가 정확히 맞아떨어진다.

esbuild가 2020년에 **"Go로 짜면 100배 빠르다"**를 증명했을 때, 생태계의 마음이 움직였다. Evan Wallace는 webpack 빌드를 20초에서 200ms로 줄였다. 그 다음 질문은 자연스러웠다 — "왜 모두 그렇게 하지 않지?"

답은 두 갈래로 갈렸다.

  • Go: GC가 있고 문법이 단순하다. 컴파일은 빠르지만 zero-cost abstraction이 부족하다. esbuild는 이 길을 갔다.
  • Rust: GC가 없고 ownership이 까다롭다. 학습 곡선은 가파르지만 진짜 시스템 수준의 성능과 안전을 동시에 얻는다. 거의 모든 후계 도구가 이 길을 갔다.

2026년 시점에서 보면 결과는 명확하다. Rust가 이겼다. swc, Turbopack, Rspack, Biome, oxc, Rolldown, Farm, Lightning CSS, tsdown — 새 도구는 거의 전부 Rust다. Go는 esbuild 하나, Zig는 Bun 하나. 나머지는 모두 Rust.


2장 · 도구 분류표 — 역할로 먼저 이해하기

도구 이름이 너무 많아서 헷갈리는데, 역할로 묶으면 단순하다. 빌드 체인은 다음 단계로 쪼개진다.

단계역할JS 시대의 대표Rust 시대의 후계
Parse소스를 AST로acorn, @babel/parserswc, oxc
TransformJSX/TS → JS, 다운레벨Babelswc, oxc-transformer
Lint정적 분석ESLintBiome, oxlint
Format코드 포매팅PrettierBiome, dprint
Resolve모듈 경로 해석enhanced-resolveoxc-resolver
Bundle모듈 그래프 → 청크webpack, Rollup, ParcelTurbopack, Rspack, Rolldown, Farm
Minify코드 압축terser, uglify-jsswc-minify, oxc-minifier, esbuild
Dev ServerHMR/번들리스webpack-dev-serverVite, Turbopack
CSS트랜스폼·미니파이postcss, cssnanoLightning CSS
RuntimeJS 실행Node.jsBun, Deno
Package Manager의존성 설치npm, yarn, pnpmBun, Volta

이걸 머릿속에 박아두면 새 도구가 나와도 "아 저건 X 단계 후계구나" 하고 위치를 잡을 수 있다.

한 가지 더 — "도구 통합" 흐름

Rust 시대의 또 다른 특징은 한 도구가 여러 단계를 합치는 것이다. Biome은 lint + format을 합쳤다. oxc는 parse + transform + lint + format + minify + resolve를 한 우산 안에 모으려 한다. Bun은 runtime + package manager + bundler + test runner를 합쳤다. 수직 통합이다.

JS 시대는 "Unix 철학 — 한 가지 일을 잘 하라"였다. Rust 시대는 "단일 AST를 공유해서 파싱을 한 번만 하자"다. 둘 다 일리가 있고, 어느 쪽이 이길지는 아직 미정이다. 다만 현재 모멘텀은 통합 쪽이다.


3장 · Turbopack — Next.js 15의 기본 dev (build는 beta)

누가 Vercel. 처음에는 Tobias Koppers (webpack 창시자)가 주도했다. 언어 Rust. 역할 Bundler + Dev server. 상태 (2026.5) Next.js 15 default dev. Build는 여전히 beta — Next.js 16에서 stable 목표.

핵심 아이디어 — 함수 단위 캐시

webpack/Vite와의 핵심 차이는 Turbo Engine이라는 캐시 레이어다. 모든 변환은 함수로 표현되고, 입력이 같으면 결과를 캐시한다. 이걸 Turbopack은 "incremental computation"이라 부른다.

// Turbo Engine은 의존성 그래프를 자동으로 추적한다
#[turbo_tasks::function]
async fn parse_module(path: FilePath) -> Result<AstVc> {
    let source = read_file(path).await?;
    Ok(swc_parse(source))
}

parse_module을 두 번 호출해도 입력이 같으면 두 번째는 캐시 히트다. 파일이 바뀌면 그 파일에 의존하는 함수만 무효화된다. 결과적으로 HMR이 거의 즉각이 된다.

현실 — 왜 build는 beta인가

2024~2025년 Turbopack은 "dev는 빠른데 build는 미완성"이라는 평이 많았다. CSS Modules 엣지케이스, Sentry 같은 webpack 플러그인 호환, 일부 module federation 시나리오에서 webpack 결과와 미묘하게 달랐다. 2026년 현재 build는 Next.js 15에서 opt-in beta. production용으로 채택할지는 팀 상황에 따라 — Vercel 호스팅 + 표준 Next.js라면 점점 안전하지만, 거대한 webpack 플러그인 자산이 있다면 아직 webpack 빌드를 유지하는 곳이 많다.

누가 써야 하나

  • Next.js 15+ 새 프로젝트 → dev에서 그냥 켜라.
  • 기존 Next.js 12~14 프로젝트 → dev만 켜고 build는 webpack 유지가 안전.
  • Next.js가 아닌 React 앱 → Turbopack을 직접 쓰는 경로는 아직 없다. Rspack이나 Vite가 답.

4장 · Rspack — ByteDance, webpack 호환의 무기

누가 ByteDance (TikTok 모회사). 메인테이너는 Han, hardfist 등. 언어 Rust. 역할 Bundler. 상태 (2026.5) v1.x stable. ByteDance 내부 수천 프로젝트에서 사용.

핵심 아이디어 — webpack API 호환

Turbopack은 "처음부터 다시 짜자"였다. Rspack은 반대다 — webpack의 API와 플러그인 시스템을 거의 그대로 호환한다. module.rules, resolve, plugins, optimization 거의 동일하다. webpack 플러그인 중 상당수가 약간의 수정으로 동작한다.

// rspack.config.js — webpack.config.js와 거의 동일
module.exports = {
  entry: './src/index.tsx',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  module: {
    rules: [
      { test: /\.tsx?$/, use: 'builtin:swc-loader' },
    ],
  },
  plugins: [
    new HtmlRspackPlugin({ template: './public/index.html' }),
  ],
};

이 호환성 전략 덕에 ByteDance 내부의 거대한 webpack 프로젝트들이 수정 거의 없이 Rspack으로 옮겨갔다. 빌드 시간이 5~10배 줄었다고 보고한다.

Rsbuild — Rspack 위의 더 친절한 레이어

Rspack은 webpack처럼 설정이 까다롭다. 그래서 ByteDance는 Rsbuild라는 상위 도구를 같이 만들었다 — Rspack을 안쪽에서 쓰지만, Vite처럼 합리적 기본값과 간결한 설정을 제공한다. 2026년 현재 Rspack 채택은 Rsbuild를 통한 경우가 더 많다.

# Rsbuild는 한 줄로 시작한다
npm create rsbuild@latest my-app

누가 써야 하나

  • 큰 webpack 프로젝트를 빠르게 마이그레이션 → Rspack.
  • 새 프로젝트인데 webpack 스타일이 익숙하다 → Rsbuild.
  • Next.js를 쓰지 않는 React 프로덕션 앱에서 빌드 속도가 결정적 → Rspack/Rsbuild는 가장 안전한 선택 중 하나.

5장 · esbuild — Go 기반 속도의 기준선

누가 Evan Wallace (Figma 공동창업자). 언어 Go. 역할 Bundler + Transformer + Minifier. 상태 (2026.5) v0.24+. 안정. 새 기능보다는 안정성에 집중.

위치

esbuild는 이 모든 흐름의 방아쇠였다. 2020년 webpack 빌드 20초를 200ms로 줄여 보였을 때, 업계는 **"네이티브 언어가 답이다"**라는 결론에 도달했다.

2026년 시점에서 esbuild의 위치는 흥미롭다. 여전히 가장 빠르지만, 직접 쓰는 경우는 줄고 있다. 이유는 다음과 같다.

  • 기능 범위가 의도적으로 좁다. Evan Wallace는 esbuild를 "라이브러리이자 기준선"으로 본다. 코드 분할(code splitting)도 실험적, plugin API도 의도적으로 제한적.
  • 다른 도구가 esbuild를 내부에서 쓴다. Vite는 dev 사전 번들에 esbuild를 쓴다. tsup도 esbuild 래퍼다. 직접 쓰는 게 아니라 숨어서 빌드 체인의 일부가 된다.

그래도 직접 쓸 만한 곳

  • 라이브러리 빌드 — 작고 빠르게 ESM/CJS 듀얼 출력.
  • 단순 CLI/스크립트 번들 — webpack을 가져올 이유가 없을 때.
  • 빌드 도구 자체의 부품 — Vite, tsup, tsdown 등이 esbuild를 부품으로 쓴다.
// esbuild를 라이브러리로 — 5줄로 끝난다
import { build } from 'esbuild';
await build({
  entryPoints: ['src/index.ts'],
  bundle: true,
  format: 'esm',
  outfile: 'dist/index.js',
  external: ['react', 'react-dom'],
});

esbuild는 사라지지 않는다. 다만 사용자의 직접 접점은 줄고, "다른 도구 안의 엔진"이 된다.


6장 · swc — Babel을 대체하는 Rust 변환기

누가 kdy1 (DongYoon Kang). Vercel이 후원, Turbopack의 트랜스파일러로 채택. 언어 Rust. 역할 Parser + Transformer + Minifier. 상태 (2026.5) stable. Next.js의 표준 트랜스파일러. Babel 대비 20~70배 빠름.

무엇을 대체했나

Babel은 한 시대를 정의한 도구였다. ES6를 ES5로 다운레벨, JSX를 변환, TypeScript를 stripping. 문제는 속도였다. JS로 짠 AST 변환은 본질적으로 느리다.

swc는 같은 일을 Rust로 한다. 인터페이스는 비슷하지만 (.swcrc vs .babelrc, JSX/TS 지원, custom plugin 가능) 속도가 다르다.

// .swcrc — Babel 설정과 거의 일대일 대응
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": false
    },
    "transform": {
      "react": {
        "runtime": "automatic"
      }
    },
    "target": "es2022"
  }
}

어디서 만나나

  • Next.js의 트랜스파일 단계 (모든 .tsx/.ts/.jsx).
  • Jest용 SWC 트랜스폼 (@swc/jest) — babel-jest 대체.
  • Storybook, Turborepo 등 다수의 Vercel 계열 도구.

Plugin — 아직 시끄러운 영역

Babel 플러그인 생태계는 거대했다. swc도 plugin API를 제공하지만, Rust 또는 WebAssembly로 짜야 한다. 진입 장벽이 높아 커뮤니티 플러그인은 Babel만큼 풍부하지 않다. 2024~2026년 swc 팀이 Wasm 기반 플러그인 API를 안정화했고, @swc/plugin-emotion 같은 사용 빈도 높은 플러그인은 이미 swc 버전이 있다. 그러나 long tail은 여전히 Babel.


7장 · Biome — Prettier + ESLint 대체 시도

누가 Biome team (Rome 프로젝트의 후속). 풀타임 개발자 다수. 언어 Rust. 역할 Formatter + Linter (한 도구에 둘 다). 상태 (2026.5) v2.x. Linter는 ESLint 규칙 상당 부분 커버, Formatter는 Prettier 거의 100% 호환.

배경 — Rome에서 Biome으로

2020년 Rome이라는 야심찬 프로젝트가 있었다. Babel 창시자 Sebastian McKenzie가 "JS 도구 체인 전체를 하나로 통합한다"는 비전으로 시작. Rust로 전환했지만 2022~2023년 자금 문제로 사실상 중단. Biome은 Rome의 fork이자 후속이다. 이름만 바뀐 게 아니라 거버넌스와 펀딩 모델이 바뀌었고, 진짜로 출하했다.

무엇이 들어 있나

  • Formatter — Prettier 거의 호환. 한 줄 명령으로 마이그레이션 가능.
  • Linter — ESLint의 권장 규칙 상당수 포팅. 일부 React/TypeScript 전용 규칙 포함.
  • Import organizereslint-plugin-import 대체.
  • 속도 — Prettier 대비 25배+, ESLint 대비 10~20배.
# 한 번에 설치, 한 번에 실행
npm i -D @biomejs/biome
npx @biomejs/biome check --apply ./src

# 또는 마이그레이션
npx @biomejs/biome migrate eslint --write
npx @biomejs/biome migrate prettier --write

한계 — 아직 ESLint를 100% 대체하진 못한다

ESLint 커뮤니티 플러그인은 수천 개다. eslint-plugin-jest, eslint-plugin-testing-library, eslint-plugin-next 등 프레임워크 특화 플러그인이 산더미. Biome은 코어 규칙은 빠르지만 커스텀 룰을 짜는 API가 ESLint만큼 성숙하지 않다. 2026년 현재 많은 팀이 "Prettier는 Biome으로, ESLint는 그대로" 같은 하이브리드를 쓴다.

누가 써야 하나

  • 새 프로젝트 → Prettier+ESLint 대신 그냥 Biome.
  • 기존 프로젝트 → Prettier는 쉽게 갈아탈 수 있고, ESLint는 일부만.
  • 모노레포 빌드 CI에서 lint/format이 병목 → 큰 효과.

8장 · oxc — 통합 파서/링터/포매터, Rolldown의 백본

누가 Boshen (싱가포르 출신 메인테이너) 외. VoidZero에 합류 (2024년). 언어 Rust. 역할 Parser, Linter (oxlint), Resolver, Minifier, Transformer, Formatter (개발 중). 상태 (2026.5) Parser와 Resolver는 production-ready. oxlint는 빠른 ESLint 대체. Minifier는 swc-minify 수준 도달. Formatter는 베타.

왜 oxc가 중요한가

JS 도구의 90%는 AST에서 시작한다. 파싱이 빠르면 그 위의 모든 게 빨라진다. oxc(Oxidation Compiler)의 목표는 **"JavaScript용 가장 빠른 AST 도구 모음을 만들고, 그 위에 모든 도구를 얹게 하자"**다.

┌────────────────────────────────────────────────────────┐
│                        oxc 코어                          │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌────────┐  │
│  │ Parser   │  │ Resolver │  │ Minifier │  │Formatter│  │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └───┬────┘  │
│       └─────────────┴─────────────┴────────────┘       │
│                       │                                 │
│              공통 AST + 공통 traversal                   │
└───────────────────────┬────────────────────────────────┘
        ┌───────────────────────────────────┐
        │      Rolldown / oxlint / etc      │
        └───────────────────────────────────┘

핵심 아이디어: AST를 한 번만 만들고, 그 위에서 lint·minify·format·transform을 다 한다. swc가 각자 파싱하는 것과 다르다.

oxlint — ESLint보다 50~100배 빠르다

oxc 안의 linter. 이름은 oxlint. 벤치마크가 ESLint 대비 50~100배 빠르다고 보고된다.

# 한 번 설치하고 한 번 실행
npx oxlint@latest

# package.json
{
  "scripts": {
    "lint": "oxlint",
    "lint:check": "oxlint --deny-warnings"
  }
}

ESLint 핵심 규칙 다수와 typescript-eslint의 일부, eslint-plugin-react, eslint-plugin-jsx-a11y 일부를 포팅했다. 100% 호환은 아니지만 CI의 첫 단계로 oxlint를 돌리고, 통과한 것에만 ESLint를 돌리는 하이브리드가 흔하다.

통합 회사 — VoidZero가 oxc를 흡수

2024년 7월 Evan You (Vue 창시자)가 VoidZero를 창업하면서 oxc 메인테이너 Boshen을 합류시켰다. 이로써 oxc·Rolldown·Vite가 한 회사 우산 아래 모였다. 이 의미는 14장에서 다시 다룬다.


9장 · Rolldown — Rollup 후속, Vite의 차세대 번들러

누가 Evan You + Rolldown core team. VoidZero가 호스팅. 언어 Rust. 역할 Bundler (Rollup 호환 API). 상태 (2026.5) Beta. Vite 7에서 옵트인 가능하며, Vite 8에서 기본 번들러가 될 예정.

Vite의 현실 — 두 개의 번들러를 쓰고 있었다

Vite의 비밀: dev와 build에 서로 다른 번들러를 쓴다.

  • Dev: 사전 번들에 esbuild, 그 외에는 번들리스 ESM.
  • Build: Rollup.

이게 문제였던 적이 있다 — dev에서 잘 되던 게 build에서 깨지거나, esbuild와 Rollup의 동작 차이가 미묘한 버그를 만들었다. Vite 팀은 오래 전부터 **"하나의 Rust 번들러로 통일하고 싶다"**고 말해왔고, 그게 Rolldown이다.

무엇을 약속하나

// rolldown.config.js — Rollup 설정과 거의 동일
import { defineConfig } from 'rolldown';

export default defineConfig({
  input: 'src/main.ts',
  output: {
    dir: 'dist',
    format: 'esm',
  },
  plugins: [
    // Rollup plugin은 (대부분) 그대로 동작
  ],
});
  • Rollup 플러그인 호환 — Rollup 생태계의 거대한 자산을 그대로 쓸 수 있게.
  • 속도 — Rollup 대비 10~30배. esbuild에 근접.
  • CommonJS 지원 — Rollup이 약했던 CJS 처리를 네이티브로.
  • Code splitting — esbuild의 약한 부분을 풀 기능으로.

누가 써야 하나

  • 2026년 현재 직접 쓰기엔 아직 이르다. Vite를 통해 간접적으로 만나게 된다.
  • 라이브러리 빌드 도구로 esbuild/tsup이 답답한 곳 → 베타 시도해볼 가치.

10장 · Farm — 떠오르는 신예

누가 brightwu 등. 중국 커뮤니티 중심. 언어 Rust. 역할 Bundler + Dev server. 상태 (2026.5) v1.x. 활발한 개발, 채택은 아직 초기.

차별점

Farm은 webpack/Vite/Rspack 사이의 빈자리를 채우려 한다.

  • dev 속도 — Vite보다 빠르다고 주장. Rust 코어 + 부분 번들링.
  • Rollup 플러그인 호환 — Vite/Rolldown과 비슷한 약속.
  • HMR이 명시적으로 빠름 — 큰 앱에서도 100ms 이내.
// farm.config.ts
import { defineConfig } from '@farmfe/core';

export default defineConfig({
  compilation: {
    input: { index: './src/main.tsx' },
    output: { path: 'dist' },
  },
  server: {
    port: 9000,
  },
});

위치

기능적으로는 Vite/Rsbuild와 비슷한 자리를 노린다. 차별화는 "Vite보다 빠르고 Rspack보다 webpack 의존이 적다." 다만 2026년 현재 선택의 강한 이유는 아직 약하다 — Vite/Rspack 둘 다 충분히 빠르고, 생태계가 더 크다. Farm은 watch 대상이지만 default 추천은 아직 아니다.


11장 · Vite 6 — Environment API, 멀티 환경

누가 Evan You, Vite core team, VoidZero. 언어 TypeScript (코어는 JS, 내부에서 esbuild/Rolldown 사용). 역할 Dev server + Build orchestrator. 상태 (2026.5) v6 stable. v7에서 Rolldown 옵트인. v8에서 Rolldown 기본.

6의 핵심 — Environment API

Vite 5까지는 "browser용 빌드"가 1급 시민이었다. 그런데 SSR, RSC, edge, worker 같은 환경이 늘면서 한 프로젝트가 여러 빌드 출력을 가지게 됐다. Vite 6의 Environment API는 이걸 명시화한다.

// vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  environments: {
    client: {
      build: {
        outDir: 'dist/client',
      },
    },
    ssr: {
      build: {
        outDir: 'dist/ssr',
        ssr: true,
      },
    },
    workerd: {
      build: {
        outDir: 'dist/worker',
      },
      resolve: {
        conditions: ['workerd', 'edge'],
      },
    },
  },
});

각 environment는 자신의 resolve.conditions, 자신의 플러그인 필터, 자신의 모듈 그래프를 가진다. 프레임워크 빌더(Nuxt, SvelteKit, SolidStart)에게 큰 무기다 — 이전엔 각자 hacky한 방법으로 SSR/CSR을 분리했는데 이제는 1급 API.

Vite의 위치 — 사실상 표준

Vite는 2020년 출시 이후 React/Vue/Svelte/Solid 등 거의 모든 프레임워크의 표준 dev 도구가 됐다. 2026년 npm 다운로드 기준 Vite가 webpack을 추월했다. Next.js만 자체 빌더(Turbopack) 트랙을 갔고, 나머지 거의 모든 메타-프레임워크가 Vite 위에 얹혀 있다.


12장 · Bun — Zig 기반 통합 런타임 + 번들러

누가 Jarred Sumner. Oven 회사. 언어 Zig. 역할 Runtime + Package manager + Bundler + Test runner. 상태 (2026.5) v1.x stable. Node.js 호환성 대폭 향상.

다른 종족

Bun은 다른 도구들과 같은 시리즈가 아니다. Bun은 Node.js 대체를 노린다. 그 안에 번들러가 들어 있을 뿐.

# package manager
bun install
# script runner
bun run dev
# test runner
bun test
# bundler
bun build src/index.ts --outdir dist
# runtime
bun src/server.ts

한 바이너리에 다 들어 있다. node + npm + tsc + webpack + jest의 자리를 한 도구로 노린다.

2026년 현실

  • package manager는 진짜 빠르다. bun installnpm install보다 5~25배 빠르다는 보고가 흔하다. 일부 팀은 Bun을 패키지 매니저로만 쓴다 (런타임은 Node 유지).
  • Runtime 호환성이 큰 폭으로 향상됐다. Express, Fastify, Hono, Elysia 거의 다 동작. Node.js 일부 native module만 문제.
  • 번들러는 esbuild와 비슷한 속도. 직접 쓰기보다 Bun 프로젝트에서 자연스럽게 쓰게 된다.
  • 테스트 러너는 Jest API 호환을 노린다. bun testjest보다 빠르다는 보고 다수.

누가 써야 하나

  • 새 서버 사이드 TS 프로젝트 → Bun을 진지하게 검토. 특히 단순 API 서버.
  • monorepo 패키지 매니저 → Bun이 답. pnpm 대비 더 빠르고, 호환성도 충분.
  • 기존 거대한 Node 프로젝트 → 운영 마이그레이션은 신중히. Native module 의존도가 핵심.

13장 · tsdown / Lightning CSS — 작지만 중요한 도구

tsdown — TypeScript 라이브러리 번들러

누가 Sxzz (Vite/Vue 컨트리뷰터). 2024년 시작. 언어 Rust (Rolldown 위에 얹은 thin wrapper). 역할 TypeScript 라이브러리 번들러 (tsup의 후속).

tsup은 esbuild 래퍼였고, esbuild의 한계를 그대로 물려받았다 (code splitting 약함, DTS 생성을 별도로 해야 함). tsdown은 Rolldown 위에 얹어 이걸 풀고자 한다.

# package.json
{
  "scripts": {
    "build": "tsdown"
  }
}

# tsdown.config.ts
import { defineConfig } from 'tsdown';

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
});

라이브러리 저자에게는 작지만 중요한 도구. ESM/CJS 듀얼 출력, 자동 DTS 생성, Rolldown 기반 빠른 빌드.

Lightning CSS — CSS의 Rust 번들러

누가 Devon Govett (Parcel 창시자). 언어 Rust. 역할 CSS parser + transformer + minifier + bundler.

postcss + cssnano + autoprefixer의 자리를 한 도구로 노린다. CSS Modules, CSS Nesting, @layer, color-mix() 등 최신 CSS를 다운레벨링한다.

왜 중요한가: Tailwind CSS 4가 내부 엔진을 Lightning CSS로 바꿨다. 2026년 기준 Tailwind v4를 쓰는 모든 프로젝트가 사실상 Lightning CSS를 쓴다.

npm i -D lightningcss

# 단독으로도 쓸 수 있다
npx lightningcss --minify --bundle --targets '>= 0.25%' src/style.css -o dist/style.css

그 외 작은 도구들

  • unbuild — UnJS 진영의 라이브러리 빌더. Rollup 기반.
  • tshy — Isaac Schlueter (npm 창시자)의 TypeScript 듀얼 빌더.
  • dprint — Rust 기반 멀티언어 포매터. Biome과 경쟁.
  • moonrepo / nx — 빌드 도구는 아니지만 빌드 오케스트레이션 (turbo와 경쟁).

14장 · VoidZero — 통합 회사가 의미하는 것 (2024년 7월)

2024년 7월 Evan You가 VoidZero라는 회사를 발표했다. Vue 생태계의 비영리적 활동을 떠나, **"JS 빌드 도구 체인 전체를 한 회사 아래 구축한다"**는 야심이다.

모인 사람

  • Evan You — Vue, Vite.
  • Boshen — oxc 메인테이너.
  • Patak (Vite core), bluwy (Vite core), 그 외 다수.
  • Sxzz — tsdown, Vue/Vite 컨트리뷰터.

Series A는 4.6M USD (Accel 리드). 작아 보이지만 오픈소스 도구 회사로서는 충분히 의미 있는 규모.

무엇을 노리나

VoidZero의 명시적 비전: "Rust 기반 통합 JS 도구 체인".

  • Parser/Resolver/Minifier — oxc.
  • Bundler — Rolldown.
  • Dev server / Build orchestrator — Vite 7/8.
  • Linter — oxlint.
  • Formatter — oxc-formatter (개발 중).
  • Test runner — Vitest (이미 광범위하게 쓰임).

각 도구는 독립적으로 쓸 수 있지만, 같은 AST와 같은 traversal을 공유한다. JS 시대의 "각 도구가 다시 파싱"이라는 비효율을 깬다.

왜 의미 있나

JS 빌드 도구는 오랫동안 개별 메인테이너의 선의에 기대왔다. Babel, webpack, Rollup, Prettier — 거의 모두 한두 명의 개인이 끌어온 프로젝트다. 그 모델은 번아웃과 자금 부족을 반복했다 (Rome이 그렇게 죽었다).

VoidZero는 회사로 모델을 바꾸는 첫 본격적 시도다. Vercel이 Turbopack/swc를 사내 프로덕트의 일부로 끄는 것과 비슷한 구조지만, VoidZero는 vendor-neutral을 표방한다 — 특정 프레임워크/플랫폼에 묶이지 않는다. Next.js·Nuxt·SvelteKit·SolidStart 누구나 쓸 수 있게.

2026년 시점에서 보면 이게 잘 굴러갈지는 아직 모른다. 다만 이 회사가 망하지 않으면 향후 5년의 JS 빌드 체인은 VoidZero가 정의한다. Vercel/Turbopack과 VoidZero/Rolldown — 두 진영의 양강 구도가 형성된 것이 2026년 풍경이다.


15장 · Cara Tool Status 2025 — 커뮤니티가 무엇을 쓰는가

Cara (전 Devographics) 가 매년 진행하는 State of JS Tooling 설문이 2025년 결과를 발표했다. 핵심 발견:

  • Vite의 만족도가 가장 높다. 사용 86%, 사용자 만족 94%.
  • Turbopack과 Rspack은 채택률이 빠르게 오르고 있다. Turbopack은 Next.js 채택에 연동, Rspack은 모노레포에서 강세.
  • esbuild는 직접 사용보다 의존성으로 묻혀 들어가는 케이스가 다수. 만족도는 여전히 매우 높음.
  • Bun의 패키지 매니저 사용은 가파르게 상승. 런타임은 아직 실험.
  • Biome 채택률은 ESLint를 추월하지 못했지만 만족도가 더 높다. 새 프로젝트의 선택이 빠르게 늘어남.
  • webpack은 여전히 가장 많이 설치되어 있지만 신규 시작자는 거의 없다. 레거시에 가까운 위치.

이 데이터는 "Rust 도구 = 미래"라는 일반론을 숫자로 뒷받침한다. 채택은 점진적이지만 신규 시작점은 거의 전부 Rust 진영으로 흐른다.


16장 · 누가 무엇을 골라야 하나 — 시나리오별 추천

시나리오 1: Next.js 앱 (신규)

  • Dev: Turbopack (Next 15 default).
  • Build: Next 16부터는 Turbopack default 예정. 그전엔 webpack.
  • 트랜스파일: swc (자동).
  • Lint/Format: oxlint + Biome, 또는 ESLint+Prettier 유지.

시나리오 2: Next.js가 아닌 React 앱 (신규)

  • 번들러: Vite 6, 또는 Rsbuild.
  • dev 서버: Vite (사실상 표준).
  • 트랜스파일: swc 또는 oxc-transformer (Vite가 내부에서 처리).
  • Lint/Format: Biome 또는 oxlint+Prettier.

시나리오 3: 라이브러리 (npm 패키지)

  • 번들러: tsdown (Rolldown 기반) 또는 tsup (esbuild 기반, 작은 라이브러리).
  • 타입: tsc로 DTS만 생성하는 게 아직 가장 안전.
  • Format: Biome.
  • Lint: oxlint + 필요한 부분만 ESLint.

시나리오 4: CLI 도구 / 단순 스크립트

  • 번들러: esbuild 직접, 또는 Bun build.
  • 런타임 옵션: Bun (단일 파일 실행 강력).

시나리오 5: 거대한 webpack 모노레포 (마이그레이션)

  • 1단계: Babel을 swc로 (가장 안전).
  • 2단계: webpack-dev-server를 Vite로 (앱 단위로).
  • 3단계: webpack을 Rspack으로 (설정 호환성 활용).
  • 4단계: ESLint를 oxlint로 (CI 첫 단계만).

시나리오 6: 백엔드 TS 서비스

  • 런타임: Bun (단순 API 서버), Node.js (성숙도 우선).
  • 번들러: tsdown 또는 esbuild.
  • 패키지 매니저: Bun, pnpm.
  • 테스트: Vitest, bun test.

결정 트리 한 줄 요약

  • 빠른 dev가 필요? → Vite (대부분), Turbopack (Next).
  • 거대 webpack을 그대로? → Rspack.
  • 라이브러리? → tsdown.
  • 린트/포맷 한 도구로? → Biome, 또는 oxlint+dprint.
  • 모든 걸 한 바이너리로? → Bun.

17장 · 마치며 — 5년 후의 모습

2020년 esbuild가 나왔을 때 "이게 시작이구나"라고 느낀 사람은 많았다. 2024년 VoidZero가 출범하고 Turbopack이 Next.js 15 default가 됐을 때, 종착지의 모습이 보이기 시작했다.

2030년의 JavaScript 빌드 체인은 이렇게 생겼을 가능성이 높다.

  • AST 공통화 — oxc 또는 swc가 거의 모든 파싱을 담당.
  • 두 개의 큰 우산 — Vercel/Turbopack/swc 와 VoidZero/Rolldown/oxc.
  • Vite는 dev 표준 — Next.js 외의 거의 모든 메타-프레임워크의 토대.
  • JS로 짠 빌드 도구는 박물관행 — webpack, Rollup, Prettier, ESLint의 신규 채택은 0에 가까움.
  • runtime/패키지 매니저는 Bun이 일부 시장 흡수 — Node를 완전히 대체하지는 않음.
  • CSS는 Lightning CSS가 표준 — Tailwind v4 채택과 함께.
  • Lint는 oxlint + 일부 ESLint 하이브리드가 다수.

이 그림이 맞을지 틀릴지는 모른다. JS 빌드 도구 역사상 가장 확실한 한 가지는 "5년 후 풍경은 항상 예상과 다르다"는 것이다. 다만 한 가지 흐름은 거의 확실하다 — JS 빌드 도구는 더 이상 JS로 짜이지 않는다. 그 방향은 되돌릴 수 없다.

좋은 시기다. 도구를 골라야 한다면 Rust 진영에서 고르자, 그리고 VoidZero와 Vercel 양쪽 트랙을 다 지켜보자. 5년 후의 표준이 그 둘 중 하나(또는 둘 모두)에서 나올 것이다.


참고 / References