ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 76

  1. Blog

Should You Leave Babel for SWC? 1.05s vs 46ms

Babel 8.0.6 vs SWC 1.16.13 vs esbuild 0.28.2 per-file transform on 501 TSX files (526 KB): medians 1.05 s / 46 ms / 83 ms. esbuild bundle of same entry 40 ms. Sample Comp0.js sizes close (1089/1121/1167 B). Leave Babel if you only strip TS/JSX; keep it for macros/unported plugins.

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. Is SWC faster than esbuild and Babel?
  3. What do you lose leaving Babel?
  4. Should you leave Babel for SWC or esbuild?
  5. Sources
  6. Related

On a 501-file TypeScript/TSX fixture (about 526 KB of source), Babel 8.0.6 took a median 1.05 s to transform every file. SWC 1.16.13 took 46 ms. esbuild 0.28.2 took 83 ms. Same machine, same files, parallel transform API for each tool.

Short answer: leave Babel for SWC or esbuild if you only need TypeScript and JSX stripped for a bundler or loader. Stay on Babel if you depend on Babel plugins that have no SWC or esbuild port. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM Linux cloud box, Node 20.19.2, tested 5 Oct 2026 (about 22:45 to 22:55 IST). Shared box; tools interleaved each round.
  • Fixture: 500 generated React function components (.tsx) plus one index.ts re-export file (501 files, 525,620 bytes). Classic JSX runtime, TypeScript types, no CSS.
  • Tools: @swc/core 1.16.13, esbuild 0.28.2, @babel/core 8.0.6 with @babel/preset-typescript 8.0.1 and @babel/preset-react 8.0.1. Target ES2020, ESM output, classic React transform.
  • Timing: five interleaved warm runs after one warmup. Each run transforms all 501 files with Promise.all over the library APIs (swc.transform, esbuild.transform, babel.transformAsync), writing one .js per input. Median wall-clock.
  • Extra: one esbuild.build bundle of the same entry (external react) for context — median 40 ms. That is a bundler path, not the same job as per-file transform.
  • One surprise: SWC beat esbuild on this per-file transform (46 ms vs 83 ms). The gap flipped when esbuild bundled the tree in one shot.
  • Not tested: minification quality, source maps, decorator plugins, SWC Wasm plugins, Babel macro plugins, Windows/macOS, a real app migration, cold process startup of each CLI.

Is SWC faster than esbuild and Babel?

ToolRoleMedianRuns (ms)
SWC 1.16.13per-file transform46 ms59 / 56 / 43 / 46 / 35
esbuild 0.28.2per-file transform83 ms85 / 83 / 83 / 92 / 73
Babel 8.0.6per-file transform1.05 s1181 / 1079 / 1038 / 1045 / 1052
esbuild 0.28.2full bundle (extra)40 ms33 / 40 / 42 / 45 / 39

On this fixture SWC was about 1.8x faster than esbuild for the transform API and about 23x faster than Babel. Babel is the one that still costs a full second on 501 small files. Sample output sizes for Comp0.js were close (Babel 1,089 B, esbuild 1,121 B, SWC 1,167 B), so the decision here is time, not payload.

If your pipeline already calls esbuild as a bundler, do not rip it out because SWC won a transform-only race. Measure the job you actually run. The Rspack 2.2.8 notes are the SWC-in-bundler path on this site; the Webpack 5.111 ESM notes are the Babel-era Webpack baseline.

What do you lose leaving Babel?

Babel's value is the plugin ecosystem. This fixture used only TypeScript + React presets. Real apps that rely on Babel macros, custom syntax plugins, or older transform plugins may have no drop-in SWC or esbuild option. SWC has its own plugin story (including Wasm plugins tied to a swc_core version); esbuild is intentionally small and rejects most Babel-style plugins.

Also match the transform to the bundler you keep. Vite leans on esbuild (and Rolldown work) for deps; Rspack leans on SWC. Swapping the transform library while leaving the bundler alone is fine for a loader experiment, but CI should time the full production build, not just transform(). The Vite 8.3.2 post is the closer next step if your app is Vite-first.

Should you leave Babel for SWC or esbuild?

SituationMy pick
Babel only strips TS/JSX for Webpack or a custom loader; no macrosPrefer SWC (or esbuild) and re-time CI
Already on Vite / esbuild for deps and transformsStay on esbuild; do not add SWC for a 40 ms micro-win
Moving Webpack to RspackTake SWC with the bundler; see the Rspack migrate path
Depends on Babel macros or unported pluginsKeep Babel for those files; split the pipeline if needed
You only care about final bundle timeBenchmark the bundler; this post measured transform APIs

Bottom line: on 501 TSX files, Babel took 1.05 s, SWC took 46 ms, and esbuild took 83 ms for the same transform job. Who should not switch yet: teams blocked on a Babel-only plugin. Everyone else still on Babel-for-TSX should measure their own tree the same way before rewriting the loader stack.

How this was made: I generated the fixture, ran every transform on the ShopperCove test box, and kept the timing JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • https://swc.rs/docs/getting-started
  • https://esbuild.github.io/api/#transform
  • https://babeljs.io/docs/babel-core
  • https://www.npmjs.com/package/@swc/core
  • https://www.npmjs.com/package/esbuild
  • https://www.npmjs.com/package/@babel/core

Related

  • https://www.shoppercove.com/blog/rspack-2-2-8-resolver-cache-memory-october-2026
  • https://www.shoppercove.com/blog/webpack-5-111-esm-output-stable-september-2026
  • https://www.shoppercove.com/blog/vite-8-3-2-renderbuilturl-bundled-dev-sourcemaps-october-2026
  • https://www.shoppercove.com/blog/vite-plus-1-0-unified-toolchain-october-2026
  • https://www.shoppercove.com/blog/oxlint-vs-eslint
  • https://www.shoppercove.com/blog/typescript-7-should-you-upgrade
  • https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
  • https://www.shoppercove.com/blog/bun-1-4-2-elysia-als-cmyk-jpeg-october-2026
swc vs esbuildbabel vs swcbabel vs esbuildshould i leave babelswc transform speedesbuild transform vs swc

Lab evidence

What I found running this

Hands-on on ShopperCove box 5 Oct 2026 ~22:45-22:55 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 20.19.2). Fixture: 500 generated React TSX components + index.ts re-exports (501 files, 525620 bytes). Versions: @swc/core 1.16.13, esbuild 0.28.2, @babel/core 8.0.6 + @babel/preset-typescript 8.0.1 + @babel/preset-react 8.0.1. API: parallel Promise.all over swc.transform / esbuild.transform / babel.transformAsync; target ES2020, ESM, classic JSX. Wall medians (5 interleaved after warmup): SWC 45.883 ms (58.6/55.8/43.1/45.9/34.6); esbuild transform 83.243 ms (84.6/83.2/83.2/92.1/73.3); Babel 1052.200 ms (1181/1079/1038/1045/1052); esbuild.build bundle (external react) 40.398 ms (32.6/40.4/41.8/45.2/38.7). Sample Comp0.js sizes: Babel 1089 B, esbuild 1121 B, SWC 1167 B. Raw: /workspace/bench-xform/res-xform.json. Not tested: minify quality, source maps, decorators, Wasm plugins, Babel macros, CLI cold start, Windows/macOS, real app migrate. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 60

    Zustand vs Redux Toolkit: 0.14 ms vs 0.68 ms per Update

    zustand 5.0.15 vs @reduxjs/toolkit 2.13.0 + react-redux 9.3.0 on React 19.3.0 (jsdom, NODE_ENV=production). 1,000 selector-subscribed rows, 300 flushSync updates x 7 trials, 2 runs: per-update median 0.137/0.139 ms vs 0.676/0.694 ms (~5x); 1 row re-rendered per update in both. Store-only: 1,376,191 vs 6,502 updates/s; Immer autoFreeze off lifts RTK to 386,966. Gzip (React external): 387 B vs 9,708 B. Fixture /workspace/bench-zustand-rtk/.

    5 Oct 2026

  • Plate 04

    Ajv vs Zod: 3.9M vs 1.1M Validations per Second

    ajv 8.20.0 (+ajv-formats 3.0.1) vs zod 4.6.5 on the same nested user shape as zod-vs-valibot. Warm medians (2k warmup + 9x50k): Ajv validate ok 3,933,337 ops/s vs zod.safeParse 1,138,406 (~3.5x). Bad input: Ajv allErrors 4,094,452 vs Zod 435,537 (~9.4x). Setup: Ajv new+addFormats+compile median 6.47 ms vs Zod build 0.17 ms; break-even ~10k validations. Browser gzip: Ajv runtime 41 KB, Ajv standalone 1.8 KB, Zod classic 93 KB, zod/mini 6.8 KB. Fixture /workspace/bench-ajv-zod/.

    5 Oct 2026

  • Plate 12

    Yarn Berry vs pnpm: 1.3s vs 0.24s Install

    Yarn 4.9.2 (Berry PnP + node-modules linker) vs pnpm 12.9.1 on one 22-dependency React+Vite app. Isolated caches (Yarn enableGlobalCache false; pnpm --store-dir). Warm medians (5): Yarn PnP 1.307 s, Yarn nm 2.471 s, pnpm 0.240 s. Lock+empty medians 1.656 / 2.789 / 0.725 s. Clean disk: Yarn PnP 246 MB; Yarn nm modules 189 MB; pnpm hardlink project 167 MB. Fixture /workspace/bench-yarn-pnpm/. Distinct from pnpm-vs-npm-vs-bun (no Yarn).

    5 Oct 2026

On this page

  1. What I tested
  2. Is SWC faster than esbuild and Babel?
  3. What do you lose leaving Babel?
  4. Should you leave Babel for SWC or esbuild?
  5. Sources
  6. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove