Skip to content

test(integration): emotion v10 격리 fixture + e2e 커버리지 + bundle config 버그 수정#2255

Merged
ohah merged 2 commits into
mainfrom
test/emotion-v10-coverage
Apr 30, 2026
Merged

test(integration): emotion v10 격리 fixture + e2e 커버리지 + bundle config 버그 수정#2255
ohah merged 2 commits into
mainfrom
test/emotion-v10-coverage

Conversation

@ohah
Copy link
Copy Markdown
Owner

@ohah ohah commented Apr 30, 2026

배경

emotion 100% 지원 목표 — v10 (legacy) 사용자 케이스 검증. v10 의 @emotion/core entry 는 v11 의 @emotion/react 와 별도 패키지라 같은 node_modules 트리에 공존이 어려움. 격리 fixture 로 해결.

발견 + 수정한 버그

packages/core/bin/zts.mjsrunBundlecompiler: 옵션을 forward 누락 — zts.config.jsoncompiler.emotion / compiler.styledComponentsbundle 모드에서 silently drop 됐다. zts build (app 모드) 는 이미 forward 하고 있어 mode 간 split 이 원인. v10 e2e 테스트가 이 버그를 노출.

  // packages/core/bin/zts.mjs:1764 (runBundle)
+ // compiler.styledComponents / compiler.emotion 도 bundle 모드에서 forward.
+ compiler: config?.compiler,

이 버그는 zts --bundle entry.ts -o out.js 를 쓰는 모든 사용자 영향. zts build 만 쓰던 사용자는 영향 없음.

추가 인프라

격리 fixture

tests/integration/fixtures/emotion-v10/
├── package.json    # @emotion/core@10, @emotion/styled@10, react@16
├── bun.lock        # commit (재현성)
└── .gitignore      # node_modules 제외

CI: cd tests/integration/fixtures/emotion-v10 && bun install 사전 실행 필요.

helpers 확장

  • EMOTION_V10_FIXTURE_NODE_MODULES / hasEmotionV10Fixture()
  • linkNodeModules({ extraRoots }) — v10 fixture 를 lookup 우선순위 첫째로
  • runZtsInDir(dir, args, { bin: "zig" | "js" }) — JS CLI (bun + bin/zts.mjs) 통한 NAPI 검증 옵션 추가. compiler.emotion 같은 JS-only 옵션은 Zig CLI 미노출이라 JS CLI 경로 필수.

테스트 커버리지

유닛 (emotion_test.zig +5 케이스):

  • @emotion/core 의 css / keyframes / 동시 import / JSX inline / alias

통합 (emotion-v10.test.ts 9 케이스)runV10Bundle({source, config, packages?}) 헬퍼로 boilerplate 흡수:

  • @emotion/core: css binding / keyframes / css+keyframes 동시 / JSX inline css (jsx pragma 포함)
  • @emotion/styled v10: styled.div / styled(Component) chain
  • 옵션: emotion: false 비활성 / emotion.autoLabel: false
  • 격리 검증: fixture 의 @emotion/core 가 실제 ^10. 인지

코드 리뷰 (3-agent /simplify)

발견된 모든 P1/P2 반영:

이슈 수정
runZtsInDir / runZtsJsInDir 17 줄 byte-for-byte 중복 bin discriminator 통합
v10 통합 테스트 9× boilerplate (~150 줄) runV10Bundle 헬퍼로 흡수
무의미한 out.length > 5000 byte count 체크 제거
유닛 테스트 naming (v10): 일관성 깨짐 @emotion/core (v10) 형태로
WHAT-narrating 주석 의미 있는 WHY 만 유지

순효과: +502 / -3 lines, 테스트는 +14 케이스 (유닛 5 + 통합 9).

검증

  • zig build test — 4203/4203 통과
  • bun test tests/emotion-v10.test.ts — 9/9 통과
  • bun test tests/css-library-smoke.test.ts (v11 회귀) — 9/9 통과
  • bun test tests/zts-config-bundler.test.ts (helpers 시그니처 변경 회귀) — 13/13 통과

🤖 Generated with Claude Code

## 배경

emotion 100% 지원 목표 — v10 (legacy) 사용자 케이스 검증 필요.
v10 의 `@emotion/core` entry 는 v11 의 `@emotion/react` 와 별도 패키지라
같은 node_modules 트리에 공존이 어려움. **격리 fixture 로 해결**.

## 발견 + 수정한 버그

`packages/core/bin/zts.mjs` 의 `runBundle` 이 `compiler:` 옵션을 forward
누락 — `zts.config.json` 의 `compiler.emotion` / `compiler.styledComponents`
가 bundle 모드에서 silently drop 됐다. `zts build` (app 모드) 는 이미 forward
하고 있었으니 mode 간 split 이 원인. v10 e2e 테스트가 이 버그를 노출.

## 추가 인프라

- `tests/integration/fixtures/emotion-v10/` — 격리된 `package.json` + `bun.lock`.
  `@emotion/core@10`, `@emotion/styled@10`, `@emotion/css@10`, `react@16` 설치.
  CI: `cd tests/integration/fixtures/emotion-v10 && bun install` 사전 실행 필요.
- `helpers.ts` 에 `EMOTION_V10_FIXTURE_NODE_MODULES` / `hasEmotionV10Fixture()`
  / `linkNodeModules({ extraRoots })` (v10 root 우선 검색) / `runZtsInDir` 의
  `bin: "zig" | "js"` 옵션 (JS CLI 통한 NAPI 검증).

## 테스트 커버리지

**유닛 (`emotion_test.zig` +5 케이스)**:
- `@emotion/core` 의 css / keyframes / 동시 import / JSX inline / alias

**통합 (`emotion-v10.test.ts` 9 케이스, `runV10Bundle` 헬퍼로 boilerplate 흡수)**:
- @emotion/core: css binding / keyframes / css+keyframes 동시 / JSX inline css
- @emotion/styled v10: styled.div / styled(Component) chain
- 옵션: emotion 비활성 / autoLabel disable
- 격리 검증: fixture 의 @emotion/core 가 실제 v10.x 인지

## 코드 리뷰 (3-agent /simplify)

발견된 모든 P1/P2 반영:
- `runZtsInDir` / `runZtsJsInDir` 17 줄 byte-for-byte 중복 → `bin` discriminator
- v10 통합 테스트 9× boilerplate (~150 줄) → `runV10Bundle` 헬퍼
- 무의미한 `out.length > 5000` byte count 체크 제거
- 유닛 테스트 naming 기존 패턴 일치 (`(v10):` → `@emotion/core (v10)`)
- WHAT-narrating 주석 제거 (의미 있는 WHY 만 유지)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ohah ohah added the enhancement New feature or request label Apr 30, 2026
@ohah ohah self-assigned this Apr 30, 2026
2nd /simplify pass 결과 반영:
- 번들 실패 시 stderr/stdout 포함해 throw — silent 빈 `out` 으로 인한
  헷갈리는 assertion 메시지 방지
- `entry` 기본값 `"index.tsx"` → `"index.ts"` (9개 중 6개 override 하던 footgun)
- JSX inline 케이스만 명시적 `entry: "index.tsx"`

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ohah ohah merged commit b312d79 into main Apr 30, 2026
17 checks passed
@ohah ohah deleted the test/emotion-v10-coverage branch April 30, 2026 03:56
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Smoke Test Results (CI)

Smoke Test Results

Project ZTS Size Time esbuild Size Time rolldown Size Time rspack Size Time Output
lodash-es OK 47KB 40ms OK 64KB 67ms OK 99KB 664ms OK 122KB 135ms MATCH
preact OK 13KB 7ms OK 15KB 9ms OK 13KB 121ms OK 13KB 116ms MATCH
date-fns OK 37KB 26ms OK 47KB 48ms OK 77KB 131ms OK 102KB 159ms MATCH
uuid OK 1.8KB 5ms OK 2.1KB 9ms OK 2.0KB 109ms OK 3.9KB 112ms MATCH
zod OK 101KB 18ms OK 119KB 18ms OK 98KB 121ms OK 147KB 135ms MATCH
axios OK 344KB 28ms FAIL 436KB 36ms OK 398KB 141ms OK 411KB 161ms MATCH
toolkit OK 32KB 19ms OK 48KB 18ms OK 33KB 145ms OK 126KB 128ms MATCH
rxjs OK 323KB 32ms OK 367KB 39ms OK 308KB 168ms OK 325KB 151ms MATCH
immer OK 16KB 8ms OK 20KB 10ms OK 18KB 118ms OK 36KB 117ms MATCH
superjson OK 23KB 7ms OK 26KB 12ms OK 24KB 122ms OK 32KB 116ms MATCH
express OK 776KB 43ms OK 1138KB 61ms OK 908KB 171ms OK 917KB 174ms MATCH
react OK 3.9KB 5ms OK 19KB 9ms OK 4.2KB 116ms OK 18KB 111ms MATCH
commander OK 67KB 12ms OK 119KB 13ms OK 100KB 119ms OK 121KB 118ms MATCH
eventemitter3 OK 6.6KB 4ms OK 7.8KB 8ms OK 9.2KB 119ms OK 10KB 109ms MATCH
ms OK 2.7KB 3ms OK 4.3KB 7ms OK 4.0KB 120ms OK 5.0KB 119ms MATCH
dotenv OK 11KB 4ms OK 14KB 8ms OK 12KB 116ms OK 14KB 110ms MATCH
jsonwebtoken OK 112KB 13ms OK 137KB 20ms OK 141KB 124ms OK 159KB 123ms MATCH
bcryptjs OK 32KB 8ms OK 46KB 10ms OK 47KB 111ms OK 60KB 115ms MATCH
clsx OK 0.6KB 3ms OK 0.6KB 7ms OK 0.7KB 107ms OK 1.5KB 108ms MATCH
tiny-invariant OK 0.5KB 3ms OK 0.5KB 7ms OK 0.6KB 117ms OK 1.5KB 108ms MATCH
tanstack-query OK 45KB 9ms OK 57KB 12ms OK 47KB 113ms OK 59KB 117ms MATCH
fast-glob OK 161KB 18ms OK 199KB 24ms OK 187KB 131ms OK 201KB 126ms MATCH
micromatch OK 79KB 12ms OK 100KB 15ms OK 100KB 127ms OK 108KB 118ms MATCH
semver OK 53KB 8ms OK 66KB 13ms OK 52KB 119ms OK 67KB 114ms MATCH
debug OK 20KB 6ms FAIL 25KB 10ms OK 24KB 109ms OK 28KB 112ms MATCH
chalk OK 13KB 5ms OK 15KB 8ms OK 13KB 119ms OK 17KB 111ms MATCH
yaml OK 205KB 20ms OK 261KB 21ms OK 228KB 137ms OK 284KB 124ms MATCH
yargs OK 165KB 19ms OK 185KB 19ms OK 167KB 127ms OK 227KB 126ms MATCH
effect OK 337KB 193ms OK 477KB 163ms OK 368KB 270ms OK 1460KB 242ms MATCH
vue OK 1058KB 101ms OK 1307KB 70ms OK 1069KB 218ms OK 1216KB 175ms MATCH
svelte OK 1.5KB 16ms OK 4.7KB 17ms OK 3.5KB 122ms OK 197KB 136ms MATCH
svelte-mount OK 91KB 27ms OK 113KB 28ms OK 93KB 143ms OK 459KB 163ms MATCH
svelte-mount-min OK 12KB 47ms OK 37KB 30ms OK 28KB 142ms OK 22KB 198ms MATCH
svelte-full OK 97KB 29ms OK 121KB 30ms OK 104KB 134ms OK 462KB 159ms MATCH
svelte-full-min OK 14KB 47ms OK 40KB 31ms OK 30KB 138ms OK 24KB 202ms MATCH
solid-js OK 0.3KB 6ms OK 2.4KB 9ms OK 2.2KB 112ms OK 23KB 113ms MATCH
three OK 243KB 139ms OK 296KB 72ms OK 276KB 180ms OK 1280KB 249ms MATCH
graphql OK 53KB 25ms OK 604KB 35ms OK 547KB 154ms OK 100KB 121ms MATCH
supabase OK 309KB 30ms OK 759KB 31ms OK 706KB 158ms OK 779KB 148ms MATCH
mobx OK 135KB 25ms OK 87KB 15ms OK 73KB 128ms OK 190KB 134ms MATCH
jotai OK 20KB 7ms OK 23KB 9ms OK 20KB 113ms OK 26KB 114ms MATCH
mitt OK 0.6KB 3ms OK 0.6KB 7ms OK 0.7KB 109ms OK 1.5KB 110ms MATCH
zustand OK 1.1KB 3ms OK 1.2KB 7ms OK 1.3KB 108ms OK 2.3KB 110ms MATCH
valtio OK 7.4KB 6ms OK 7.5KB 9ms OK 8.3KB 109ms OK 24KB 113ms MATCH
react-dom OK 444KB 34ms OK 539KB 24ms OK 447KB 146ms OK 534KB 131ms MATCH
d3 OK 83KB 61ms OK 100KB 76ms OK 97KB 169ms OK 150KB 195ms MATCH
hono OK 41KB 9ms OK 59KB 14ms OK 52KB 125ms OK 68KB 121ms MATCH
dayjs OK 10KB 5ms OK 14KB 8ms OK 11KB 118ms OK 8.9KB 111ms MATCH
nanoid OK 0.8KB 3ms OK 0.9KB 7ms OK 0.9KB 117ms OK 2.6KB 113ms MATCH
zlib OK 95KB 20ms OK 112KB 16ms OK 102KB 125ms OK 222KB 130ms MATCH
fp-ts OK 2.4KB 9ms OK 70KB 14ms OK 100KB 125ms OK 50KB 122ms MATCH
neverthrow OK 11KB 5ms OK 18KB 9ms OK 13KB 124ms OK 19KB 114ms MATCH
drizzle-orm OK 13KB 14ms OK 30KB 28ms OK 14KB 118ms OK 35KB 128ms MATCH
tslib OK 0.8KB 6ms OK 0.8KB 8ms OK 0.8KB 110ms OK 18KB 114ms MATCH
iconv-lite OK 300KB 10ms OK 543KB 16ms OK 320KB 126ms OK 325KB 120ms MATCH
qs OK 65KB 12ms OK 95KB 23ms OK 81KB 118ms OK 92KB 119ms MATCH
change-case OK 3.0KB 4ms OK 3.2KB 8ms OK 3.4KB 107ms OK 8.0KB 110ms MATCH
path-to-regexp OK 7.5KB 5ms OK 14KB 8ms OK 8.1KB 106ms OK 15KB 109ms MATCH
mime-types OK 178KB 12ms OK 235KB 15ms OK 198KB 120ms OK 164KB 134ms MATCH
ajv OK 205KB 21ms OK 243KB 21ms OK 208KB 132ms OK 239KB 126ms MATCH
cac OK 16KB 6ms OK 18KB 8ms OK 16KB 118ms OK 19KB 114ms MATCH
defu OK 1.9KB 3ms OK 2.1KB 7ms OK 1.8KB 106ms OK 3.0KB 112ms MATCH
pathe OK 3.0KB 6ms OK 3.4KB 9ms OK 3.0KB 110ms OK 13KB 114ms MATCH
destr OK 2.0KB 3ms OK 2.1KB 7ms OK 1.9KB 107ms OK 3.1KB 108ms MATCH
hookable OK 5.3KB 4ms OK 5.9KB 8ms OK 5.2KB 114ms OK 9.3KB 114ms MATCH
minimatch OK 45KB 11ms OK 56KB 13ms OK 47KB 120ms OK 90KB 118ms MATCH
cheerio OK 462KB 80ms OK 2186KB 89ms OK 1748KB 259ms OK 2387KB 216ms MATCH
is-glob OK 4.0KB 4ms OK 6.4KB 7ms OK 4.9KB 106ms OK 6.0KB 111ms MATCH
glob-parent OK 5.3KB 4ms OK 8.4KB 8ms OK 6.4KB 107ms OK 7.9KB 111ms MATCH
escape-string-regexp OK 0.3KB 3ms OK 0.4KB 7ms OK 0.4KB 111ms OK 1.5KB 108ms MATCH
fast-deep-equal OK 1.5KB 3ms OK 2.9KB 7ms OK 2.3KB 127ms OK 3.2KB 111ms MATCH
deepmerge OK 4.0KB 3ms OK 5.5KB 7ms OK 4.5KB 109ms OK 6.0KB 112ms MATCH
color-convert OK 23KB 7ms OK 30KB 10ms OK 27KB 120ms OK 27KB 112ms MATCH
picomatch OK 46KB 9ms OK 58KB 11ms OK 55KB 116ms OK 61KB 116ms MATCH
type-is OK 186KB 13ms OK 244KB 17ms OK 210KB 119ms OK 179KB 135ms MATCH
object-assign OK 2.1KB 3ms OK 3.8KB 7ms OK 2.8KB 117ms OK 4.3KB 107ms MATCH
has-flag OK 0.4KB 3ms OK 0.5KB 6ms OK 0.5KB 110ms OK 1.7KB 109ms MATCH
p-limit OK 2.6KB 3ms OK 3.0KB 7ms OK 2.7KB 120ms OK 5.2KB 110ms MATCH
strip-ansi OK 0.7KB 3ms OK 0.8KB 7ms OK 0.8KB 114ms OK 2.2KB 108ms MATCH
ansi-regex OK 0.4KB 3ms OK 0.5KB 6ms OK 0.4KB 104ms OK 1.8KB 108ms MATCH
wrap-ansi OK 31KB 6ms OK 35KB 11ms OK 34KB 110ms OK 38KB 115ms MATCH
supports-color OK 3.6KB 3ms OK 3.8KB 7ms OK 3.5KB 120ms OK 5.7KB 110ms MATCH
cross-spawn OK 14KB 6ms OK 18KB 10ms OK 15KB 119ms OK 19KB 111ms MATCH
lru-cache OK 21KB 7ms OK 23KB 10ms OK 22KB 116ms OK 18KB 111ms MATCH
signal-exit OK 5.2KB 4ms OK 6.8KB 7ms OK 6.5KB 116ms OK 12KB 111ms MATCH
which OK 6.8KB 5ms OK 9.5KB 9ms OK 7.8KB 109ms OK 8.7KB 109ms MATCH
string-width OK 23KB 4ms OK 25KB 9ms OK 25KB 117ms OK 27KB 112ms MATCH
safe-buffer OK 0.5KB 3ms OK 3.8KB 7ms OK 1.8KB 121ms OK 3.8KB 108ms MATCH
bytes OK 3.4KB 3ms OK 4.3KB 7ms OK 4.3KB 105ms OK 5.5KB 107ms MATCH
depd OK 8.6KB 4ms OK 12KB 8ms OK 11KB 111ms OK 13KB 108ms MATCH
merge-descriptors OK 1.0KB 3ms OK 2.3KB 7ms OK 1.8KB 114ms OK 2.9KB 107ms MATCH
content-type OK 3.3KB 3ms OK 5.3KB 7ms OK 4.2KB 117ms OK 6.0KB 108ms MATCH
cookie OK 3.4KB 4ms OK 9.8KB 7ms OK 5.6KB 123ms OK 13KB 108ms MATCH
cjs-define-property-member-value OK 0.7KB 2ms OK 2.0KB 6ms OK 0.7KB 114ms OK 1.5KB 113ms MATCH
object-freeze-pure-call OK 0.2KB 2ms OK 0.2KB 5ms OK 0.2KB 108ms OK 1.1KB 109ms MATCH
object-assign-pure-call OK 0.2KB 2ms OK 0.2KB 6ms OK 0.2KB 115ms OK 1.1KB 109ms MATCH
cjs-esmodule-marker-pruning OK 0.7KB 2ms OK 2.0KB 6ms OK 0.7KB 107ms OK 1.5KB 106ms MATCH
cjs-module-exports-object-member-value OK 0.7KB 3ms OK 2.0KB 6ms OK 0.6KB 115ms OK 2.4KB 109ms MATCH
on-finished OK 5.2KB 4ms OK 6.9KB 8ms OK 6.7KB 122ms OK 8.3KB 110ms MATCH
statuses OK 3.7KB 3ms OK 5.8KB 8ms OK 5.3KB 114ms OK 6.1KB 110ms MATCH
etag OK 1.9KB 3ms OK 3.7KB 7ms OK 3.4KB 107ms OK 4.6KB 106ms MATCH
vary OK 3.0KB 3ms OK 3.7KB 7ms OK 3.5KB 107ms OK 5.1KB 107ms MATCH
flat OK 1.1KB 3ms OK 1.3KB 7ms OK 1.3KB 108ms OK 4.9KB 111ms MATCH
retry OK 6.3KB 4ms OK 8.6KB 7ms OK 7.0KB 112ms OK 7.3KB 112ms MATCH
camelcase OK 3.5KB 3ms OK 3.7KB 7ms OK 3.5KB 115ms OK 4.5KB 111ms MATCH
decamelize OK 1.2KB 3ms OK 1.3KB 6ms OK 1.3KB 118ms OK 3.0KB 110ms MATCH
memoize-one OK 1.2KB 3ms OK 3.1KB 8ms OK 2.3KB 118ms OK 2.4KB 114ms MATCH
rfdc OK 5.9KB 4ms OK 8.2KB 8ms OK 6.4KB 120ms OK 7.7KB 108ms MATCH
ohash OK 3.7KB 4ms OK 4.1KB 8ms OK 3.9KB 110ms OK 4.6KB 110ms MATCH
nanoevents OK 0.5KB 3ms OK 0.5KB 7ms OK 0.6KB 118ms OK 1.6KB 109ms MATCH
typebox OK 104KB 21ms OK 116KB 30ms OK 123KB 134ms OK 182KB 148ms MATCH
ts-pattern OK 10KB 5ms OK 12KB 9ms OK 11KB 112ms OK 9.6KB 114ms MATCH
valibot OK 6.1KB 20ms OK 6.8KB 17ms OK 8.0KB 115ms OK 193KB 130ms MATCH
ts-results-es OK 19KB 5ms OK 22KB 8ms OK 26KB 107ms OK 34KB 114ms MATCH
remeda OK 2.3KB 13ms OK 2.6KB 21ms OK 2.5KB 126ms OK 3.7KB 123ms MATCH
nanostores OK 4.4KB 4ms OK 5.6KB 9ms OK 4.6KB 120ms OK 8.2KB 113ms MATCH
ky OK 26KB 7ms OK 30KB 10ms OK 30KB 123ms OK 49KB 117ms MATCH
typedi OK 13KB 5ms OK 27KB 10ms OK 28KB 122ms OK 25KB 114ms MATCH
io-ts OK 15KB 15ms OK 104KB 17ms OK 118KB 126ms OK 102KB 124ms MATCH
type-fest OK 0.1KB 2ms OK 0.1KB 5ms OK 0.1KB 116ms OK 0.9KB 107ms MATCH
arktype OK 258KB 29ms OK 297KB 32ms OK 273KB 155ms OK 382KB 161ms MATCH
kysely OK 226KB 32ms OK 371KB 42ms OK 357KB 151ms OK 471KB 175ms MATCH
lodash-es@es5 OK 12KB 35ms OK 18KB 57ms OK 28KB 145ms FAIL - 0ms MATCH
clsx@es5 OK 0.6KB 3ms OK 0.6KB 7ms OK 0.7KB 114ms FAIL - 0ms MATCH
ms@es5 OK 2.6KB 3ms OK 4.5KB 7ms OK 4.0KB 115ms FAIL - 0ms MATCH
deepmerge@es5 OK 4.0KB 3ms OK 5.7KB 8ms OK 4.5KB 111ms FAIL - 0ms MATCH
fast-deep-equal@es5 OK 1.5KB 3ms OK 3.0KB 7ms OK 2.3KB 108ms FAIL - 0ms MATCH
semver@es5 OK 62KB 9ms FAIL - 11ms OK 52KB 117ms FAIL - 0ms MATCH
lodash-es@es2015 OK 12KB 35ms OK 18KB 56ms OK 28KB 152ms FAIL - 0ms MATCH
superjson@es2015 OK 23KB 7ms OK 27KB 13ms OK 24KB 128ms FAIL - 0ms MATCH
flat@es2017 OK 1.1KB 3ms OK 1.3KB 7ms OK 1.3KB 119ms FAIL - 0ms MATCH
defu@es2017 OK 1.9KB 3ms OK 2.8KB 8ms OK 1.8KB 113ms FAIL - 0ms MATCH
picomatch@es2018 OK 46KB 9ms OK 58KB 11ms OK 55KB 116ms FAIL - 0ms MATCH
semver@es2019 OK 53KB 9ms OK 66KB 13ms OK 52KB 124ms FAIL - 0ms MATCH
clsx@es2019 OK 0.6KB 3ms OK 0.6KB 7ms OK 0.6KB 114ms FAIL - 0ms MATCH
nanoid@es2019 OK 0.8KB 3ms OK 1.0KB 8ms OK 0.9KB 116ms FAIL - 0ms MATCH
dayjs@es2020 OK 10KB 5ms OK 14KB 9ms OK 11KB 121ms FAIL - 0ms MATCH
ohash@es2020 OK 3.8KB 4ms OK 4.8KB 8ms OK 3.9KB 107ms FAIL - 0ms MATCH
lru-cache@es2021 OK 31KB 9ms OK 35KB 10ms OK 22KB 116ms FAIL - 0ms MATCH
nanostores@es2021 OK 1.6KB 4ms OK 2.2KB 8ms OK 1.6KB 106ms FAIL - 0ms MATCH
lodash-es@chrome80 OK 47KB 35ms OK 64KB 58ms OK 99KB 148ms FAIL - 0ms MATCH
clsx@chrome49 OK 0.6KB 3ms OK 0.6KB 7ms OK 0.7KB 114ms FAIL - 0ms MATCH
dayjs@safari14 OK 10KB 5ms OK 14KB 8ms OK 11KB 112ms FAIL - 0ms MATCH
nanoid@node16 OK 0.8KB 3ms OK 0.9KB 7ms OK 0.9KB 106ms FAIL - 0ms DIFF

Size Comparison (ZTS vs smallest of esbuild/rolldown/rspack)

Project ZTS esbuild rolldown rspack Baseline Ratio Status
mobx 135KB 87KB 73KB 190KB rolldown 1.85x
lru-cache@es2021 31KB 35KB 22KB - rolldown 1.42x ⚠️
type-fest 0.1KB 0.1KB 0.1KB 0.9KB esbuild 1.35x ⚠️
cjs-module-exports-object-member-value 0.7KB 2.0KB 0.6KB 2.4KB rolldown 1.22x ⚠️
semver@es5 62KB - 52KB - rolldown 1.20x ⚠️
lru-cache 21KB 23KB 22KB 18KB rspack 1.16x ⚠️
dayjs 10KB 14KB 11KB 8.9KB rspack 1.14x ⚠️
mime-types 178KB 235KB 198KB 164KB rspack 1.09x
ts-pattern 10KB 12KB 11KB 9.6KB rspack 1.08x
cjs-define-property-member-value 0.7KB 2.0KB 0.7KB 1.5KB rolldown 1.06x
destr 2.0KB 2.1KB 1.9KB 3.1KB rolldown 1.05x
rxjs 323KB 367KB 308KB 325KB rolldown 1.05x
type-is 186KB 244KB 210KB 179KB rspack 1.04x
supports-color 3.6KB 3.8KB 3.5KB 5.7KB rolldown 1.03x
zod 101KB 119KB 98KB 147KB rolldown 1.03x
cjs-esmodule-marker-pruning 0.7KB 2.0KB 0.7KB 1.5KB rolldown 1.02x
preact 13KB 15KB 13KB 13KB rolldown 1.02x
defu@es2017 1.9KB 2.8KB 1.8KB - rolldown 1.02x
defu 1.9KB 2.1KB 1.8KB 3.0KB rolldown 1.02x
hookable 5.3KB 5.9KB 5.2KB 9.3KB rolldown 1.02x
semver@es2019 53KB 66KB 52KB - rolldown 1.01x
semver 53KB 66KB 52KB 67KB rolldown 1.01x
cac 16KB 18KB 16KB 19KB rolldown 1.01x
pathe 3.0KB 3.4KB 3.0KB 13KB rolldown 1.01x
ansi-regex 0.4KB 0.5KB 0.4KB 1.8KB rolldown 1.00x
nanostores@es2021 1.6KB 2.2KB 1.6KB - rolldown 0.99x
yargs 165KB 185KB 167KB 227KB rolldown 0.99x
react-dom 444KB 539KB 447KB 534KB rolldown 0.99x
vue 1058KB 1307KB 1069KB 1216KB rolldown 0.99x
jotai 20KB 23KB 20KB 26KB rolldown 0.99x
ajv 205KB 243KB 208KB 239KB rolldown 0.99x
valtio 7.4KB 7.5KB 8.3KB 24KB esbuild 0.98x
decamelize 1.2KB 1.3KB 1.3KB 3.0KB rolldown 0.98x
camelcase 3.5KB 3.7KB 3.5KB 4.5KB rolldown 0.97x
dotenv 11KB 14KB 12KB 14KB rolldown 0.97x
chalk 13KB 15KB 13KB 17KB rolldown 0.97x
svelte-mount 91KB 113KB 93KB 459KB rolldown 0.97x
nanostores 4.4KB 5.6KB 4.6KB 8.2KB rolldown 0.96x
ohash@es2020 3.8KB 4.8KB 3.9KB - rolldown 0.95x
minimatch 45KB 56KB 47KB 90KB rolldown 0.95x
tanstack-query 45KB 57KB 47KB 59KB rolldown 0.95x
p-limit 2.6KB 3.0KB 2.7KB 5.2KB rolldown 0.95x
toolkit 32KB 48KB 33KB 126KB rolldown 0.95x
arktype 258KB 297KB 273KB 382KB rolldown 0.94x
strip-ansi 0.7KB 0.8KB 0.8KB 2.2KB rolldown 0.94x
iconv-lite 300KB 543KB 320KB 325KB rolldown 0.94x
superjson@es2015 23KB 27KB 24KB - rolldown 0.94x
zlib 95KB 112KB 102KB 222KB rolldown 0.94x
cross-spawn 14KB 18KB 15KB 19KB rolldown 0.94x
svelte-full 97KB 121KB 104KB 462KB rolldown 0.94x
ohash 3.7KB 4.1KB 3.9KB 4.6KB rolldown 0.93x
clsx 0.6KB 0.6KB 0.7KB 1.5KB esbuild 0.93x
clsx@chrome49 0.6KB 0.6KB 0.7KB - esbuild 0.93x
clsx@es5 0.6KB 0.6KB 0.7KB - esbuild 0.93x
clsx@es2019 0.6KB 0.6KB 0.6KB - esbuild 0.93x
path-to-regexp 7.5KB 14KB 8.1KB 15KB rolldown 0.93x
rfdc 5.9KB 8.2KB 6.4KB 7.7KB rolldown 0.93x
superjson 23KB 26KB 24KB 32KB rolldown 0.93x
wrap-ansi 31KB 35KB 34KB 38KB rolldown 0.92x
drizzle-orm 13KB 30KB 14KB 35KB rolldown 0.92x
react 3.9KB 19KB 4.2KB 18KB rolldown 0.92x
change-case 3.0KB 3.2KB 3.4KB 8.0KB esbuild 0.92x
immer 16KB 20KB 18KB 36KB rolldown 0.92x
has-flag 0.4KB 0.5KB 0.5KB 1.7KB esbuild 0.92x
tslib 0.8KB 0.8KB 0.8KB 18KB rolldown 0.92x
effect 337KB 477KB 368KB 1460KB rolldown 0.92x
string-width 23KB 25KB 25KB 27KB esbuild 0.91x
dayjs@es2020 10KB 14KB 11KB - rolldown 0.91x
dayjs@safari14 10KB 14KB 11KB - rolldown 0.91x
valibot 6.1KB 6.8KB 8.0KB 193KB esbuild 0.91x
zustand 1.1KB 1.2KB 1.3KB 2.3KB esbuild 0.90x
flat@es2017 1.1KB 1.3KB 1.3KB - rolldown 0.90x
flat 1.1KB 1.3KB 1.3KB 4.9KB rolldown 0.90x
yaml 205KB 261KB 228KB 284KB rolldown 0.90x
remeda 2.3KB 2.6KB 2.5KB 3.7KB rolldown 0.90x
typebox 104KB 116KB 123KB 182KB esbuild 0.89x
retry 6.3KB 8.6KB 7.0KB 7.3KB rolldown 0.89x
uuid 1.8KB 2.1KB 2.0KB 3.9KB rolldown 0.89x
ky 26KB 30KB 30KB 49KB rolldown 0.88x
nanoevents 0.5KB 0.5KB 0.6KB 1.6KB esbuild 0.88x
mitt 0.6KB 0.6KB 0.7KB 1.5KB esbuild 0.88x
three 243KB 296KB 276KB 1280KB rolldown 0.88x
tiny-invariant 0.5KB 0.5KB 0.6KB 1.5KB esbuild 0.88x
deepmerge@es5 4.0KB 5.7KB 4.5KB - rolldown 0.87x
deepmerge 4.0KB 5.5KB 4.5KB 6.0KB rolldown 0.87x
which 6.8KB 9.5KB 7.8KB 8.7KB rolldown 0.87x
escape-string-regexp 0.3KB 0.4KB 0.4KB 1.5KB esbuild 0.87x
d3 83KB 100KB 97KB 150KB rolldown 0.86x
nanoid@es2019 0.8KB 1.0KB 0.9KB - rolldown 0.86x
vary 3.0KB 3.7KB 3.5KB 5.1KB rolldown 0.86x
nanoid 0.8KB 0.9KB 0.9KB 2.6KB rolldown 0.86x
axios 344KB 436KB 398KB 411KB rolldown 0.86x
nanoid@node16 0.8KB 0.9KB 0.9KB - rolldown 0.86x
color-convert 23KB 30KB 27KB 27KB rolldown 0.86x
fast-glob 161KB 199KB 187KB 201KB rolldown 0.86x
ts-results-es 19KB 22KB 26KB 34KB esbuild 0.86x
object-freeze-pure-call 0.2KB 0.2KB 0.2KB 1.1KB esbuild 0.86x
express 776KB 1138KB 908KB 917KB rolldown 0.85x
picomatch@es2018 46KB 58KB 55KB - rolldown 0.85x
picomatch 46KB 58KB 55KB 61KB rolldown 0.85x
eventemitter3 6.6KB 7.8KB 9.2KB 10KB esbuild 0.84x
object-assign-pure-call 0.2KB 0.2KB 0.2KB 1.1KB esbuild 0.84x
debug 20KB 25KB 24KB 28KB rolldown 0.83x
glob-parent 5.3KB 8.4KB 6.4KB 7.9KB rolldown 0.82x
jsonwebtoken 112KB 137KB 141KB 159KB esbuild 0.82x
bytes 3.4KB 4.3KB 4.3KB 5.5KB esbuild 0.81x
depd 8.6KB 12KB 11KB 13KB rolldown 0.81x
is-glob 4.0KB 6.4KB 4.9KB 6.0KB rolldown 0.81x
qs 65KB 95KB 81KB 92KB rolldown 0.80x
signal-exit 5.2KB 6.8KB 6.5KB 12KB rolldown 0.80x
micromatch 79KB 100KB 100KB 108KB esbuild 0.79x
neverthrow 11KB 18KB 13KB 19KB rolldown 0.79x
content-type 3.3KB 5.3KB 4.2KB 6.0KB rolldown 0.78x
date-fns 37KB 47KB 77KB 102KB esbuild 0.78x
hono 41KB 59KB 52KB 68KB rolldown 0.78x
on-finished 5.2KB 6.9KB 6.7KB 8.3KB rolldown 0.78x
object-assign 2.1KB 3.8KB 2.8KB 4.3KB rolldown 0.75x
lodash-es@chrome80 47KB 64KB 99KB - esbuild 0.73x
lodash-es 47KB 64KB 99KB 122KB esbuild 0.73x
statuses 3.7KB 5.8KB 5.3KB 6.1KB rolldown 0.69x
bcryptjs 32KB 46KB 47KB 60KB esbuild 0.68x
lodash-es@es2015 12KB 18KB 28KB - esbuild 0.68x
lodash-es@es5 12KB 18KB 28KB - esbuild 0.68x
commander 67KB 119KB 100KB 121KB rolldown 0.67x
ms@es5 2.6KB 4.5KB 4.0KB - rolldown 0.67x
ms 2.7KB 4.3KB 4.0KB 5.0KB rolldown 0.66x
fast-deep-equal@es5 1.5KB 3.0KB 2.3KB - rolldown 0.65x
fast-deep-equal 1.5KB 2.9KB 2.3KB 3.2KB rolldown 0.65x
kysely 226KB 371KB 357KB 471KB rolldown 0.63x
cookie 3.4KB 9.8KB 5.6KB 13KB rolldown 0.61x
svelte-full-min 14KB 40KB 30KB 24KB rspack 0.60x
merge-descriptors 1.0KB 2.3KB 1.8KB 2.9KB rolldown 0.59x
etag 1.9KB 3.7KB 3.4KB 4.6KB rolldown 0.57x
svelte-mount-min 12KB 37KB 28KB 22KB rspack 0.55x
typedi 13KB 27KB 28KB 25KB rspack 0.54x
memoize-one 1.2KB 3.1KB 2.3KB 2.4KB rolldown 0.53x
graphql 53KB 604KB 547KB 100KB rspack 0.53x
supabase 309KB 759KB 706KB 779KB rolldown 0.44x
svelte 1.5KB 4.7KB 3.5KB 197KB rolldown 0.44x
safe-buffer 0.5KB 3.8KB 1.8KB 3.8KB rolldown 0.29x
cheerio 462KB 2186KB 1748KB 2387KB rolldown 0.26x
io-ts 15KB 104KB 118KB 102KB rspack 0.15x
solid-js 0.3KB 2.4KB 2.2KB 23KB rolldown 0.13x
fp-ts 2.4KB 70KB 100KB 50KB rspack 0.05x

Average ratio (vs smallest): 0.87x | Smaller: 120 | Similar(±10%): 17 | Larger: 7

Auto-generated by CI on 2026-04-30 04:02 UTC

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Benchmark Results (CI)

macos-latest

transpile — small (100 lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 3 2 4 1.0x
esbuild 5 4 5 1.7x
Bun 6 5 8 2.0x
oxc (node) 63 58 68 21.0x
SWC 116 109 124 38.7x

transpile — medium (1K lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 4 3 4 1.0x
esbuild 4 4 5 1.0x
Bun 6 5 8 1.5x
oxc (node) 62 55 65 15.5x
SWC 122 114 127 30.5x

transpile — large (5K lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
esbuild 4 4 4 1.0x
ZTS 9 8 9 2.3x
Bun 10 9 12 2.5x
oxc (node) 69 60 82 17.3x
SWC 135 127 145 33.8x

bundle — small (10 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 3 3 4 1.0x
esbuild 7 7 8 2.3x
Bun 7 7 9 2.3x
rspack 143 104 265 47.7x
rolldown 233 133 378 77.7x
webpack 390 367 436 130.0x

bundle — medium (50 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 4 4 4 1.0x
Bun 7 7 7 1.8x
esbuild 8 8 8 2.0x
rspack 146 113 168 36.5x
rolldown 205 106 334 51.3x
webpack 395 381 412 98.8x

bundle — large (200 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 8 8 8 1.0x
Bun 8 8 9 1.0x
esbuild 12 12 12 1.5x
rolldown 118 104 171 14.8x

small (100 lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 85 82 89 1.0x
CLI (subprocess) 4446 4372 5955 52.3x
WASM (.wasm) FAIL - - -

medium (1K lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 908 885 987 1.0x
CLI (subprocess) 34357 33098 39678 37.8x
WASM (.wasm) FAIL - - -

large (5K lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 4551 4450 4615 1.0x
CLI (subprocess) 98257 92964 110157 21.6x
WASM (.wasm) FAIL - - -

xlarge (10K lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 10147 9093 11360 1.0x
CLI (subprocess) 99119 96840 106624 9.8x
WASM (.wasm) FAIL - - -

ubuntu-latest

transpile — small (100 lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 2 2 2 1.0x
esbuild 2 2 2 1.0x
Bun 3 3 3 1.5x
oxc (node) 32 31 35 16.0x
SWC 97 94 101 48.5x

transpile — medium (1K lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
esbuild 2 2 2 1.0x
Bun 4 4 4 2.0x
ZTS 5 4 5 2.5x
oxc (node) 32 30 35 16.0x
SWC 98 96 100 49.0x

transpile — large (5K lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
esbuild 2 2 2 1.0x
Bun 11 11 11 5.5x
ZTS 19 18 19 9.5x
oxc (node) 32 31 33 16.0x
SWC 121 119 123 60.5x

bundle — small (10 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 3 3 3 1.0x
Bun 5 5 6 1.7x
esbuild 6 6 6 2.0x
rolldown 110 105 116 36.7x
rspack 116 114 117 38.7x
webpack 511 507 514 170.3x

bundle — medium (50 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 4 4 4 1.0x
Bun 6 6 6 1.5x
esbuild 7 7 8 1.8x
rolldown 110 108 113 27.5x
rspack 122 119 124 30.5x
webpack 512 504 520 128.0x

bundle — large (200 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
Bun 10 9 10 1.0x
ZTS 11 10 11 1.1x
esbuild 14 14 15 1.4x
rolldown 122 119 125 12.2x

small (100 lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 222 214 230 1.0x
CLI (subprocess) 7659 7616 9586 34.5x
WASM (.wasm) FAIL - - -

medium (1K lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 2513 2497 2544 1.0x
CLI (subprocess) 70025 69486 73465 27.9x
WASM (.wasm) FAIL - - -

large (5K lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 13059 12862 13280 1.0x
CLI (subprocess) 215681 214298 216170 16.5x
WASM (.wasm) FAIL - - -

xlarge (10K lines)

Method Median (us) Min (us) Max (us) vs fastest
NAPI (.node) 26500 25936 26766 1.0x
CLI (subprocess) 222062 221436 228760 8.4x
WASM (.wasm) FAIL - - -

windows-latest

transpile — small (100 lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 11 10 13 1.0x
Bun 19 18 21 1.7x
oxc (node) 68 66 72 6.2x

transpile — medium (1K lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 13 12 14 1.0x
Bun 20 19 21 1.5x
oxc (node) 68 66 71 5.2x

transpile — large (5K lines)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
Bun 21 19 22 1.0x
ZTS 28 24 33 1.3x
oxc (node) 72 71 75 3.4x

bundle — small (10 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 16 15 16 1.0x
Bun 39 37 41 2.4x

bundle — medium (50 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 23 22 24 1.0x
Bun 41 38 44 1.8x

bundle — large (200 modules)

Tool Avg (ms) Min (ms) Max (ms) vs fastest
ZTS 45 39 51 1.0x
Bun 49 48 49 1.1x

small (100 lines)

Method Median (us) Min (us) Max (us) vs fastest
CLI (subprocess) 15111 14174 17495 1.0x
NAPI (.node) FAIL - - -
WASM (.wasm) FAIL - - -

medium (1K lines)

Method Median (us) Min (us) Max (us) vs fastest
CLI (subprocess) 76351 73922 80059 1.0x
NAPI (.node) FAIL - - -
WASM (.wasm) FAIL - - -

large (5K lines)

Method Median (us) Min (us) Max (us) vs fastest
CLI (subprocess) 227382 212352 326220 1.0x
NAPI (.node) FAIL - - -
WASM (.wasm) FAIL - - -

xlarge (10K lines)

Method Median (us) Min (us) Max (us) vs fastest
CLI (subprocess) 231143 213347 304810 1.0x
NAPI (.node) FAIL - - -
WASM (.wasm) FAIL - - -

Auto-generated by CI on 2026-04-30 04:06 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant