Skip to main content
Technology & EngineeringBuild Tools174 lines

Swc

SWC compiler configuration for fast TypeScript and JavaScript transpilation and minification

Quick Summary31 lines
You are an expert in SWC for high-performance JavaScript and TypeScript compilation, transpilation, and minification.

## Key Points

- Use SWC as a drop-in replacement for Babel when build speed is the primary bottleneck. API surface is intentionally similar.
- Set `jsc.target` to match your deployment environment to avoid unnecessary polyfill-like transforms.
- Use `@swc/jest` to speed up test suites that are bottlenecked on TypeScript transpilation.
- For monorepos, share `.swcrc` configuration via a base file and extend it per package as needed.
- Combine SWC transpilation with a separate `tsc --noEmit` step for type checking, since SWC strips types without validating them.
- Use `swc.minify` as a standalone minifier if you only need minification and not full bundling.
- **No type checking**: Like esbuild, SWC strips TypeScript types without checking them. Always run `tsc --noEmit` in CI.
- **Babel plugin incompatibility**: SWC does not support Babel plugins. If you depend on a specific Babel plugin with no SWC equivalent, you cannot migrate that transform.
- **Path aliases not resolved**: SWC only transpiles; it does not resolve path aliases like `@/`. You still need a bundler or `tsc-alias` for path resolution.
- **React runtime setting**: If you see `React is not defined` errors, ensure `jsc.transform.react.runtime` is set to `"automatic"` for React 17+ JSX transform.

## Quick Example

```bash
npm install --save-dev @swc/core @swc/cli
# For use with Webpack:
npm install --save-dev swc-loader
# For use with Jest:
npm install --save-dev @swc/jest
```

```bash
npx swc src -d dist --source-maps --config-file .swcrc
npx swc src/index.ts -o dist/index.js
```
skilldb get build-tools-skills/SwcFull skill: 174 lines
Paste into your CLAUDE.md or agent config

SWC — Build Tools

You are an expert in SWC for high-performance JavaScript and TypeScript compilation, transpilation, and minification.

Core Philosophy

Overview

SWC (Speedy Web Compiler) is a Rust-based compiler platform that can transpile TypeScript/JavaScript, minify code, and bundle modules at speeds far exceeding Babel. It supports modern ECMAScript features, JSX, TypeScript decorators, and can be used standalone, as a Webpack loader (swc-loader), or as the compiler backend in tools like Next.js and Parcel.

Setup & Configuration

Installation

npm install --save-dev @swc/core @swc/cli
# For use with Webpack:
npm install --save-dev swc-loader
# For use with Jest:
npm install --save-dev @swc/jest

.swcrc

{
  "$schema": "https://swc.rs/schema.json",
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "react": {
        "runtime": "automatic",
        "importSource": "react"
      },
      "decoratorVersion": "2022-03"
    },
    "target": "es2020",
    "minify": {
      "compress": true,
      "mangle": true
    }
  },
  "module": {
    "type": "es6",
    "strict": true
  },
  "minify": true,
  "sourceMaps": true
}

CLI Usage

npx swc src -d dist --source-maps --config-file .swcrc
npx swc src/index.ts -o dist/index.js

Core Patterns

Webpack Integration

module.exports = {
  module: {
    rules: [
      {
        test: /\.[jt]sx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'swc-loader',
          options: {
            jsc: {
              parser: { syntax: 'typescript', tsx: true },
              transform: { react: { runtime: 'automatic' } },
              target: 'es2020',
            },
          },
        },
      },
    ],
  },
};

Jest Integration

// jest.config.js
module.exports = {
  transform: {
    '^.+\\.(t|j)sx?$': [
      '@swc/jest',
      {
        jsc: {
          parser: { syntax: 'typescript', tsx: true },
          transform: { react: { runtime: 'automatic' } },
        },
      },
    ],
  },
};

Programmatic API

const swc = require('@swc/core');

const output = await swc.transform(sourceCode, {
  filename: 'input.tsx',
  jsc: {
    parser: { syntax: 'typescript', tsx: true },
    target: 'es2020',
  },
  sourceMaps: true,
});

console.log(output.code);
console.log(output.map);

Minification Only

const { code, map } = await swc.minify(inputCode, {
  compress: {
    dead_code: true,
    drop_console: true,
    passes: 2,
  },
  mangle: true,
  sourceMap: true,
});

Best Practices

  • Use SWC as a drop-in replacement for Babel when build speed is the primary bottleneck. API surface is intentionally similar.
  • Set jsc.target to match your deployment environment to avoid unnecessary polyfill-like transforms.
  • Use @swc/jest to speed up test suites that are bottlenecked on TypeScript transpilation.
  • For monorepos, share .swcrc configuration via a base file and extend it per package as needed.
  • Combine SWC transpilation with a separate tsc --noEmit step for type checking, since SWC strips types without validating them.
  • Use swc.minify as a standalone minifier if you only need minification and not full bundling.

Common Pitfalls

  • No type checking: Like esbuild, SWC strips TypeScript types without checking them. Always run tsc --noEmit in CI.
  • Decorator version mismatch: SWC supports multiple decorator proposals. Ensure decoratorVersion matches what your framework expects ("2022-03" for the TC39 standard, "2021-12" for the legacy TypeScript variant).
  • Babel plugin incompatibility: SWC does not support Babel plugins. If you depend on a specific Babel plugin with no SWC equivalent, you cannot migrate that transform.
  • Path aliases not resolved: SWC only transpiles; it does not resolve path aliases like @/. You still need a bundler or tsc-alias for path resolution.
  • React runtime setting: If you see React is not defined errors, ensure jsc.transform.react.runtime is set to "automatic" for React 17+ JSX transform.

Anti-Patterns

Over-engineering for hypothetical scale. Building for millions of users when you have hundreds adds complexity without value. Solve today's problems first.

Ignoring the existing ecosystem. Reinventing functionality that mature libraries already provide well wastes time and introduces unnecessary risk.

Premature abstraction. Creating elaborate frameworks and utilities before you have enough concrete cases to know what the abstraction should look like produces the wrong abstraction.

Neglecting error handling at boundaries. Internal code can trust its inputs, but system boundaries (user input, APIs, file I/O) require defensive validation.

Skipping documentation for obvious code. What is obvious to you today will not be obvious to your colleague next month or to you next year.

Install this skill directly: skilldb add build-tools-skills

Get CLI access →