Web: Vite 8 (Rolldown). React Native: Metro (+ Hermes V1, precompiled iOS binaries). Monorepo: pnpm workspaces + Turborepo. Expo for managed velocity.
RN bundler alternative for module federation / super-apps → Re.Pack 5 (worth the complexity when independent teams need independent JS release cadences within one app — Callstack's own criterion)
want the Rolldown/Rollup plugin ecosystem on RN (experimental) → Rollipop — early alpha, prototype only, not an Expo path
slow RN CI → prebuilt binaries (RNRepo) and/or Rock build caching
Babel is the Metro bottleneck → react-native-swc (SWC) or facetpack (OXC; early — pin + keep the Babel fallback)
Pear app → esbuild-bundle to dist (desktop) or Metro + bare-pack for the Bare worker (mobile), not the web/Metro defaults — see RB-E-P2P
new web project → Vite; legacy web → webpack/Rspack
Options & tradeoffs
the field considered — and why each one isn’t the default here
option
tradeoff
evidence
Metro
RN bundler
2.7M/wk · ships in 10/34
Vite 8 / Rspack 2 / webpack
web bundlers; Vite 8 defaults to the Rust Rolldown bundler; Rspack 2 adds RSC + 2.1 ships the Rust React Compiler via its built-in SWC loader (7–13x the Babel plugin); Vite default for new web
129.8M/wk · ships in 9/34
Turborepo / Nx + pnpm/yarn workspaces
monorepo task graph + caching
Expo vs bare RN
managed velocity vs native control
react-native-swc
Rust/SWC Metro transform — faster than Babel; custom Babel plugins need SWC equivalents (e.g. worklets plugin for Reanimated)
facetpack (early)
@ecrindigital/facetpack — Rust/OXC Metro transformer (claims ~36x Babel transforms), one-line metro.config, Babel fallback for Flow packages, Doctor CLI; v0.2 (2026-01), early-stage
85/wk
RNRepo (Software Mansion)
prebuilt native binaries via Maven; cuts CI build time (~50% reported)
Re.Pack 5 (Rspack)
Metro alternative on Rust-based Rspack; module federation / super-apps
Rock (Callstack)
native build-artifact caching (reported 35min → <4min); works with Metro or Re.Pack
Rollipop (early alpha)
Metro replacement powered by Rolldown (the Vite team's Rust bundler) — inherits the Rollup/Rolldown plugin ecosystem, Yarn PnP by default, dev dashboard; bare RN CLI only (no Expo); early-alpha, not production
Vite+ (beta)
VoidZero's unified toolchain — one entry point over Vite, Vitest, Rolldown, tsdown, Oxlint, Oxfmt; MIT; framework-agnostic; BETA (2026-07) — 'stable, but not yet complete', migration command may need manual follow-up
npm weekly downloads (from the corpus's last signals run): vite 129.8M · esbuild 252.8M · @react-native/metro-config 2.7M · metro 10.3M · webpack 41.3M · @ecrindigital/facetpack 85
Verified notes
ENGINE + BUILD (verified vs RN 0.84 blog): Hermes V1 is the DEFAULT JS engine since RN 0.84 (2026-02-11; experimental opt-in from 0.82, also opt-in in Expo SDK 55) — automatic if already on Hermes. RN 0.84 also ships PRECOMPILED iOS binaries by default (fetched at pod install, faster builds) and raised the minimum to Node 22.11+. RN is on a bi-monthly release cadence. Prebuilt native libraries (RN 0.83 artefacts, RNRepo) are the broader trend. BUNDLERS: Metro stays the RN default (RN 0.79 added ~3x faster cold start); Expo SDK 56 extends the trend with prebuilt XCFrameworks for its most complex modules (~16% faster median clean iOS builds, verified vs the SDK 56 changelog); Re.Pack 5 (on Rspack) is the main alternative, and Rollipop (leegeunhyeok/rollipop, early alpha per its repo) now brings Rolldown — the same Rust bundler behind Vite 8 — directly to the RN side; remote-JS Chrome debugging was removed in RN 0.79 (use RN DevTools). Rollipop verified vs its repo 2026-06-30 (early-alpha, not production). WEB TOOLCHAIN: a Rust wave — Vite 8 on Rolldown (1.0; ~10–30x Rollup), the Oxc family (Oxlint/Oxfmt), Bun; Cloudflare acquired VoidZero (Vite/Vitest/Rolldown/Oxc) — tools stay MIT. Vite+ BETA (2026-07-02, verified vs the VoidZero announcement; 2nd signal after TWiR #289's watch flag): the consolidation made product — one CLI over the whole VoidZero stack, MIT, framework-agnostic; beta, so watch rather than migrate existing multi-tool setups yet. Adversarially stress-tested 2026-06-25 (SURVIVES, high): Vite 8 shipped stable (2026-03) with Rolldown GA as the default; the Rust React-Compiler napi pullback affects only that compiler's JS path, not Rolldown-as-bundler; Metro stays the RN default. UPDATE 2026-07-06: the Rust React Compiler has since merged into SWC and ships in Rspack 2.1 (7–13x the Babel version, verified vs the Rspack 2.1 blog) — Rolldown's pullback is a Rolldown-integration choice, not a dead Rust port.
Canonical reading
Editorial annotations on why each piece matters — the articles themselves are the originals; read them there.
The first-principles explainer for WHY the JS toolchain is going Rust — memory safety, no GC, real parallelism, the redundant-parsing problem — mapping the whole landscape (esbuild, SWC, Oxc/Biome, Rspack, Rolldown). Durable cross-cutting context, not a single release.
Why maintaining two pipelines (esbuild + Rollup) was unsustainable and how Rolldown unifies dev/prod on one Rust bundler (10-30x faster), with Oxc semantic analysis driving better tree-shaking. The primary source for the Vite+Rolldown+Oxc consolidation.
Exactly what Metro's inlineRequires Babel transform does, why React/RN stay hoisted, why default imports aren't inlined, and how rnx-kit's esbuild path differs (real tree-shaking vs startup-only). The canonical Metro startup-mechanics reference.
Why RN Android builds are slow (conservative Gradle/Metro/C++ defaults) and how parallel Gradle, dynamic Metro workers, ccache, and single-architecture builds cut times from 20+ min to 2-5 min, with benchmarks. The RN-CI build-perf dimension the other readings here don't cover.
Watching
Curated talks, podcasts & videos — the A/V companion to the reading list.
Walkthrough of what actually happens between `npx expo run` and an installable artifact — the Gradle/Xcode stages behind APK/AAB/IPA and where Metro's bundle lands in them. The A/V companion to this entry's build-pipeline facts. (Verified via YouTube oEmbed: title + author.)
The reviewed long-form essay behind this entry — the why, not a how-to. Also on GitHub.
About build tooling, bundlers & monorepos (React & React Native)
Diataxis: Explanation. This page builds understanding of the build/bundler decision —
the reasoning behind the pick. It is not a tutorial: the candidate list and one-line
tradeoffs live in the index entry RB-E-BUILD; the feedback-loop side (CI, lint, hooks) is
RB-E-DX. Read this for the why.
Two toolchains, one trend
The first thing to get straight: web and React Native have separate build toolchains, and
they're moving at different speeds.
Web is in the middle of a churn — the "bundler wars" — that is now resolving toward
Rust. Vite 8 ships on Rolldown (a Rust bundler), unifying what used to be two
pipelines (esbuild for dev, Rollup for prod). The broader wave is the same: SWC, the Oxc
family (Oxlint/Oxfmt), Bun, Rspack — all Rust/native, all chasing speed. Cloudflare
acquiring VoidZero (Vite/Vitest/Rolldown/Oxc) signals this consolidation; the tools stay MIT.
React Native is steadier: Metro remains the default bundler, and the action is in
the native build (Gradle/Xcode) and the JS engine, not in swapping bundlers.
The durable trend across both is Rust is eating the toolchain — not as fashion, but
because native code without a GC buys real, compounding build-speed wins. That's the lens for
reading any specific tool choice.
The default, and why
Web: Vite 8 (Rolldown). React Native: Metro (+ Hermes V1, precompiled iOS binaries).
Monorepo: pnpm workspaces + Turborepo. Expo for managed velocity.
On the web, Vite is the default for new projects — fast dev server, and now a unified Rust
production bundler. On React Native, Metro stays the default not by inertia but because
it's tightly integrated with RN's resolution, Hermes, and the New Architecture's codegen;
RN 0.79 already gave it ~3× faster cold start. The engine question is settled too: Hermes
V1 is the default JS engine since RN 0.84, which also shipped precompiled iOS binaries
(faster pod install builds) and raised the floor to Node 22.11+ (verified against the
RN 0.84 blog). For monorepos, pnpm workspaces + Turborepo give a cached, parallel task
graph. And Expo is the managed-velocity choice — it owns a large slice of the build/release
pipeline so you don't have to.
The landscape, and when each one wins
Metro — the RN default; integrated, Hermes-aware, New-Arch-codegen-aware. You don't replace
it casually. RN-side build speed problems are better solved by caching and transforms than by
swapping the bundler (below).
Vite 8 / Rspack 2 / webpack (web) — Vite (on Rolldown) is the new-project default; Rspack
(Rust) is the webpack-compatible high-performance path and adds RSC support; webpack remains for
legacy. The selection axis is greenfield-vs-legacy and how much you value Vite's DX.
Re.Pack 5 (Rspack) — the main Metro alternative for RN, on Rust-based Rspack; reach for it
specifically for module federation / super-apps, not as a general Metro replacement.
react-native-swc — a Rust/SWC Metro transform, faster than Babel; the answer when Babel is
the Metro bottleneck (note: custom Babel plugins need SWC equivalents — e.g. the worklets
plugin for Reanimated).
RNRepo / Rock (native build caching) — RN's slowest step is usually the native build, not
the JS bundle. RNRepo (prebuilt native binaries via Maven) and Rock (native build-
artifact caching) attack that directly — the lever for slow RN CI, with large reported wins.
Turborepo / Nx + pnpm/yarn workspaces — monorepo task graph + caching; the standard way to
make many-package repos build incrementally.
Expo vs bare RN — managed velocity vs native control. Expo owns more of the toolchain
(builds, updates, config); bare gives full control at the cost of owning it yourself.
Tradeoffs and failure modes to name out loud
Swapping Metro to "go fast." RN's bottleneck is usually the native build or Babel, not
Metro itself. Reach for native build caching (Rock/RNRepo) or react-native-swc before
replacing the bundler; replace Metro (Re.Pack) for module federation, not for raw speed.
Chasing the newest Rust tool mid-project. The web toolchain is consolidating fast;
rewriting a working build to the bundler-of-the-month is churn. New project → Vite; existing
working build → migrate only on a concrete pain.
Letting Babel rot the RN build. If the Metro transform is the bottleneck, that's a
fixable, measurable problem (react-native-swc) — but mind the custom-plugin parity gap.
Confusing build with DX. The bundler is one piece; the feedback loop (CI gates, lint,
hooks) is what keeps the build honest — that's RB-E-DX, not this entry.
How it interacts with the rest of the stack
Native (RB-E-NATIVE). Codegen, precompiled iOS binaries, and Hermes V1 are the build-
time face of the New Architecture; this entry and that one describe the same machine from the
build and the runtime side.
DX (RB-E-DX). Monorepo task running, CI, and lint/format live there; the bundler choice
feeds into that loop.
RN versions (RB-E-RN-VERSIONS). Hermes-V1-default, precompiled iOS, and the Node-22.11
floor are version-pinned facts; verify a specific row against the RN blog.
React core (RB-E-REACT-CORE). The React Compiler plugs into the build (Babel/SWC/Oxc/
Vite); your bundler choice determines how you enable it.
In one paragraph
Treat web and RN as two toolchains with one shared trend — Rust is eating the build for
speed. On the web, default to Vite 8 (Rolldown) and only migrate a working build for a
real reason. On React Native, keep Metro (with Hermes V1 default and precompiled
iOS since RN 0.84), and fix slowness where it actually is — native build caching (Rock/RNRepo)
or an SWC transform — rather than swapping the bundler (Re.Pack is for module federation, not
raw speed). Use pnpm + Turborepo for monorepos and Expo for managed velocity, and keep
the feedback-loop concerns in RB-E-DX.