GitPedia

React native swc

⚡️ SWC-powered transformer & minifier for Metro

From oblador·Updated June 26, 2026·View on GitHub·

- 🔧 Drop-in replacement for Metro Babel transform worker and minifier - 🦀 All transformation in Rust, no Babel in sight - 🏎️ Fast: transform worker is ~8× faster & full real world bundling ~3× faster - ⚡️ Battery friendly: 15× less CPU utilization - 🚇 Feature parity with Metro: HMR, inline requires, `Platform.select()` substituion, constant folding, delta bundles etc - 🔤 Native support for Flow, TypeScript, ESM, CJS, JSX - 🧵 Worklet/Reanimated support without Babel through custom SWC plugi... The project is written primarily in TypeScript, distributed under the MIT License license, first published in 2026. Key topics include: metro, react-native, swc, swc-plugin.

Latest release: v0.1.5
May 31, 2026View Changelog →

react-native-swc

SWC-powered transformer for Metro

CI
npm (@react-native-swc/core)
License: MIT
Follow oblador on GitHub
Follow trastknast on X

  • 🔧 Drop-in replacement for Metro Babel transform worker and minifier
  • 🦀 All transformation in Rust, no Babel in sight
  • 🏎️ Fast: transform worker is ~8× faster & full real world bundling ~3× faster
  • ⚡️ Battery friendly: 15× less CPU utilization
  • 🚇 Feature parity with Metro: HMR, inline requires, Platform.select() substituion, constant folding, delta bundles etc
  • 🔤 Native support for Flow, TypeScript, ESM, CJS, JSX
  • 🧵 Worklet/Reanimated support without Babel through custom SWC plugin
  • 🔌 Support for SWC plugins and process.env inlining
  • ⚛️ Expo Plugin for seamless integration

Install

sh
yarn add -D @react-native-swc/core

If your app uses react-native-reanimated:

sh
yarn add -D @react-native-swc/worklets-plugin

Setup

Expo (managed / CNG) — config plugin

Add @react-native-swc/core to app.json:

json
{ "expo": { "plugins": ["@react-native-swc/core"] } }
sh
npx expo prebuild

The plugin writes (or updates) a metro.config.js wired up to withSwcTransformer. If react-native-worklets is listed in your dependencies, the worklets SWC plugin is registered automatically. Any EXPO_PUBLIC_* env vars present at metro start are inlined into the bundle, matching Expo's default Babel pipeline. If you already have a manual withSwcTransformer call, the plugin leaves your config alone.

Disable worklet auto-detection if needed:

json
["@react-native-swc/core", { "worklets": false }]

Note. Expo config plugins run only during expo prebuild (and eas build, which invokes prebuild). Running expo start alone does not re-run plugins.

Bare React Native / Expo (manual)

js
// metro.config.js const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const { withSwcTransformer } = require('@react-native-swc/core'); module.exports = withSwcTransformer(mergeConfig(getDefaultConfig(__dirname), {}));

For Expo without the config plugin, swap @react-native/metro-config for expo/metro-config. To match Expo's default EXPO_PUBLIC_* env-var inlining, forward those vars through swcConfig.envs:

js
// metro.config.js const { getDefaultConfig } = require('expo/metro-config'); const { withSwcTransformer } = require('@react-native-swc/core'); /** @type {import('@react-native-swc/core').SwcTransformerOptions} */ const swcConfig = { envs: Object.fromEntries( Object.entries(process.env).filter(([k, v]) => k.startsWith('EXPO_PUBLIC_')), ), }; module.exports = withSwcTransformer(getDefaultConfig(__dirname), swcConfig);

process.env.EXPO_PUBLIC_FOO references in your source are then replaced with the literal value at bundle time. Anything not prefixed with EXPO_PUBLIC_ is left alone.

Worklets (react-native-reanimated) — manual

js
// metro.config.js const { getDefaultConfig } = require('@react-native/metro-config'); const { withSwcTransformer } = require('@react-native-swc/core'); /** @type {import('@react-native-swc/core').SwcTransformerOptions} */ const swcConfig = { plugins: [ [ '@react-native-swc/worklets-plugin', { pluginVersion: require('react-native-worklets/package.json').version, }, ], ], }; module.exports = withSwcTransformer(getDefaultConfig(__dirname), swcConfig);

Configuration

withSwcTransformer(metroConfig, swcOptions?) exposes an intentionally narrow surface — everything that affects Metro correctness is owned by the transform worker:

ts
interface SwcTransformerOptions { plugins?: ReadonlyArray<[string, Record<string, unknown>]>; /** * `process.env.FOO`-style replacements to inline at build time. Values are * JSON-encoded for you and merged with the worker's built-ins (`NODE_ENV`, * `EXPO_OS`, …). E.g. `{ API_URL: "https://x" }` replaces * `process.env.API_URL` with the literal string `"https://x"`. */ envs?: Record<string, string>; }

Limitations

  • Custom Babel plugins from babel.config.js are not executed. Reanimated is covered by @react-native-swc/worklets-plugin in this repo, for other use cases see SWC plugin directory.
  • TypeScript sources must be isolatedModules-compatible. SWC parses each file in isolation.
  • Flow handling is automatic. User .js files are parsed as Flow only if they carry an @flow / @noflow pragma or if they first fail to parse as plain JavaScript.

Contributing

See CONTRIBUTING.md.

License

MIT.

Contributors

Showing top 2 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from oblador/react-native-swc via the GitHub API.Last fetched: 6/29/2026