SWC (Speedy Web Compiler) is a Rust-based JavaScript/TypeScript compiler that's 20-70x faster than Babel. It handles transpilation, minification, and bundling with native performance. Next.js uses SWC as its default compiler since v13.
| 1 | # Standalone CLI |
| 2 | npm install -D @swc/cli @swc/core |
| 3 | |
| 4 | # With webpack (swc-loader) |
| 5 | npm install -D @swc/core swc-loader |
| 6 | |
| 7 | # With Vite (vite-plugin-swc) |
| 8 | npm install -D vite-plugin-swc |
| 9 | |
| 10 | # With Next.js — already built-in! |
| 11 | # No installation needed — use next.config.js |
| 1 | # Transpile a file |
| 2 | npx swc src/index.ts -o dist/index.js |
| 3 | |
| 4 | # Transpile directory |
| 5 | npx swc src -d dist |
| 6 | |
| 7 | # With configuration |
| 8 | npx swc src -d dist --config-file .swcrc |
| 9 | |
| 10 | # Minify |
| 11 | npx swc src -o dist/index.min.js --minify |
| 12 | |
| 13 | # Watch mode |
| 14 | npx swc src -d dist --watch |
| 1 | { |
| 2 | "jsc": { |
| 3 | "parser": { |
| 4 | "syntax": "typescript", |
| 5 | "tsx": true, |
| 6 | "decorators": true, |
| 7 | "dynamicImport": true |
| 8 | }, |
| 9 | "transform": { |
| 10 | "react": { |
| 11 | "runtime": "automatic", |
| 12 | "development": false |
| 13 | }, |
| 14 | "legacyDecorator": true, |
| 15 | "decoratorMetadata": true |
| 16 | }, |
| 17 | "target": "es2022", |
| 18 | "loose": false, |
| 19 | "externalHelpers": false |
| 20 | }, |
| 21 | "minify": true, |
| 22 | "sourceMaps": true |
| 23 | } |
| 1 | // webpack.config.js — replace babel-loader with swc-loader |
| 2 | module.exports = { |
| 3 | module: { |
| 4 | rules: [ |
| 5 | { |
| 6 | test: /\.(ts|tsx|js|jsx)$/, |
| 7 | exclude: /node_modules/, |
| 8 | use: { |
| 9 | loader: "swc-loader", |
| 10 | options: { |
| 11 | jsc: { |
| 12 | parser: { syntax: "typescript", tsx: true }, |
| 13 | transform: { |
| 14 | react: { runtime: "automatic" }, |
| 15 | }, |
| 16 | }, |
| 17 | }, |
| 18 | }, |
| 19 | }, |
| 20 | ], |
| 21 | }, |
| 22 | }; |
| 1 | // vite.config.ts |
| 2 | import { defineConfig } from "vite"; |
| 3 | import swc from "vite-plugin-swc"; |
| 4 | |
| 5 | export default defineConfig({ |
| 6 | plugins: [ |
| 7 | swc({ |
| 8 | jsc: { |
| 9 | parser: { |
| 10 | syntax: "typescript", |
| 11 | tsx: true, |
| 12 | decorators: true, |
| 13 | }, |
| 14 | transform: { |
| 15 | react: { |
| 16 | runtime: "automatic", |
| 17 | }, |
| 18 | }, |
| 19 | }, |
| 20 | }), |
| 21 | ], |
| 22 | }); |
| Aspect | SWC | Babel |
|---|---|---|
| Language | Rust | JavaScript |
| Speed | 20-70x faster | Baseline |
| Plugin ecosystem | Growing (Rust-based) | Massive (JS-based) |
| Configuration | Simpler (.swcrc) | Complex (presets + plugins) |
| Used by | Next.js, Vite, Parcel | Create React App, many legacy |
best practice
SWC can minify JavaScript as a Terser alternative. Next.js and many Webpack setups use SWC minify for faster production builds.
| 1 | { |
| 2 | "jsc": { |
| 3 | "target": "es2022", |
| 4 | "minify": { |
| 5 | "compress": { |
| 6 | "unused": true, |
| 7 | "drop_console": false |
| 8 | }, |
| 9 | "mangle": true |
| 10 | } |
| 11 | }, |
| 12 | "minify": true |
| 13 | } |
warning
Next.js uses SWC by default for Fast Refresh transforms and compilation. Custom Babel configs can disable SWC — prefer SWC plugins when available.
| 1 | /** @type {import('next').NextConfig} */ |
| 2 | const nextConfig = { |
| 3 | // SWC is default — remove .babelrc unless you truly need Babel |
| 4 | compiler: { |
| 5 | // Strip console.* in production (optional) |
| 6 | removeConsole: process.env.NODE_ENV === "production", |
| 7 | // Emotion / styled-components SWC helpers when needed: |
| 8 | // emotion: true, |
| 9 | // styledComponents: true, |
| 10 | }, |
| 11 | }; |
| 12 | |
| 13 | module.exports = nextConfig; |
best practice
@swc/jest replaces ts-jest / babel-jest for faster unit test transforms.
| 1 | module.exports = { |
| 2 | transform: { |
| 3 | "^.+\\.(t|j)sx?$": [ |
| 4 | "@swc/jest", |
| 5 | { |
| 6 | jsc: { |
| 7 | parser: { syntax: "typescript", tsx: true }, |
| 8 | transform: { react: { runtime: "automatic" } }, |
| 9 | }, |
| 10 | }, |
| 11 | ], |
| 12 | }, |
| 13 | testEnvironment: "jsdom", |
| 14 | }; |
SWC plugins are typically WASM/Rust. The ecosystem is smaller than Babel's. Common needs (React, Emotion, legacy decorator patterns) are covered; exotic Babel plugins may force a hybrid setup.
| Need | SWC approach | Fallback |
|---|---|---|
| React Refresh | Built-in / framework | — |
| Emotion | SWC Emotion plugin / Next compiler | Babel plugin |
| Custom AST codemod | Write Rust/WASM plugin | Keep Babel for that file set |
| FormatJS / i18n extract | Check SWC plugin availability | Babel or separate extract step |
| Aspect | SWC | esbuild |
|---|---|---|
| Language | Rust | Go |
| Primary role | Compiler / minify / transforms | Bundler + transform |
| Used heavily by | Next.js, Rspack builtin loader | Vite dep optimize, tsup |
| Typechecking | No | No |
info
| 1 | # 1. Inventory .babelrc presets/plugins |
| 2 | # 2. Map each to SWC jsc.transform / plugins |
| 3 | # 3. Swap babel-loader → swc-loader (or builtin:swc-loader on Rspack) |
| 4 | # 4. Run unit + E2E; compare production bundles |
| 5 | # 5. Delete Babel deps when green |
| 6 | |
| 7 | npm uninstall @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript babel-loader |
| 8 | npm install -D @swc/core swc-loader |
note
- Exclude node_modules except packages that ship modern syntax you must transpile.
- Reuse .swcrc across Jest, CLI, and Webpack to avoid drift.
- Prefer jsc.target aligned with your browserslist — over-transpiling wastes bytes and CPU.
- Measure CI: Babel → SWC often yields larger gains than micro-tuning Webpack chunk config.
Community
Get help on Slack, Discord or VIP
Stuck on a guide? Join the community and ask.