SWC Complete Guide | Rust-Based JavaScript Compiler

SWC Complete Guide | Rust-Based JavaScript Compiler

이 글의 핵심

SWC (Speedy Web Compiler) is a super-fast JavaScript/TypeScript compiler written in Rust. It's 20x faster than Babel and powers Next.js, Parcel, and Vite.

Introduction

SWC (Speedy Web Compiler) is a TypeScript/JavaScript compiler and bundler written in Rust. It’s designed to be a drop-in replacement for Babel with dramatically better performance.

Performance Comparison

Compiler10,000 filesSingle core
Babel95s95s
SWC4.7s4.7s

20x faster!

1. Installation

npm install --save-dev @swc/core @swc/cli

Standalone Usage

# Compile single file
npx swc src/index.js -o dist/index.js

# Compile directory
npx swc src -d dist

# Watch mode
npx swc src -d dist --watch

2. Configuration

// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true
    },
    "transform": {
      "react": {
        "runtime": "automatic"
      }
    },
    "target": "es2020"
  },
  "module": {
    "type": "es6"
  }
}

3. JavaScript Transpilation

ES6+ to ES5

// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "ecmascript"
    },
    "target": "es5"
  }
}
// Input
const add = (a, b) => a + b;
class User {
  constructor(name) {
    this.name = name;
  }
}

// Output (ES5)
var add = function(a, b) {
  return a + b;
};
var User = function User(name) {
  this.name = name;
};

4. TypeScript

npm install --save-dev @swc/core
// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": false,
      "decorators": true
    },
    "target": "es2020"
  }
}
// input.ts
interface User {
  name: string;
  age: number;
}

const user: User = {
  name: 'Alice',
  age: 30
};
npx swc input.ts -o output.js

5. React/JSX

// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true
    },
    "transform": {
      "react": {
        "runtime": "automatic", // React 17+
        "pragma": "React.createElement",
        "pragmaFrag": "React.Fragment"
      }
    }
  }
}
// Input
function App() {
  return <div>Hello, SWC!</div>;
}

// Output (automatic runtime)
import { jsx as _jsx } from 'react/jsx-runtime';

function App() {
  return _jsx('div', { children: 'Hello, SWC!' });
}

6. Minification

SWC includes a super-fast minifier:

npm install --save-dev @swc/core
// swc.config.js
module.exports = {
  minify: true,
  jsc: {
    minify: {
      compress: {
        unused: true
      },
      mangle: true
    }
  }
};
npx swc src/index.js -o dist/index.min.js --config-file swc.config.js

7. Node.js Integration

@swc/register

npm install --save-dev @swc/register
// require-hook.js
require('@swc/register');
require('./typescript-code.ts');

Programmatic API

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

swc.transform('const x = 1', {
  jsc: {
    parser: {
      syntax: 'ecmascript'
    },
    target: 'es5'
  }
}).then(output => {
  console.log(output.code);
});

8. Next.js Integration

Next.js 12+ uses SWC by default:

// next.config.js
module.exports = {
  // SWC is enabled by default
  swcMinify: true, // Use SWC for minification
};

Features:

  • ✅ Faster builds (5x)
  • ✅ Faster refresh
  • ✅ Styled Components support
  • ✅ Jest transforms

9. Webpack Integration

npm install --save-dev swc-loader
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: 'swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'typescript',
                tsx: true
              }
            }
          }
        }
      }
    ]
  }
};

10. Vite Integration

npm install --save-dev @vitejs/plugin-react-swc
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react-swc';

export default defineConfig({
  plugins: [react()]
});

11. Jest Integration

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

12. Advanced Features

Decorators

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    }
  }
}
@sealed
class User {
  @readonly
  name: string;
}

Const Enums

{
  "jsc": {
    "parser": {
      "syntax": "typescript"
    },
    "transform": {
      "constModules": {
        "globals": {
          "myLib": {
            "VERSION": "1.0.0"
          }
        }
      }
    }
  }
}

Optimization

{
  "jsc": {
    "minify": {
      "compress": {
        "arguments": true,
        "arrows": true,
        "booleans": true,
        "collapse_vars": true,
        "comparisons": true,
        "computed_props": true,
        "conditionals": true,
        "dead_code": true,
        "directives": true,
        "drop_console": true,
        "drop_debugger": true,
        "evaluate": true,
        "expression": false,
        "hoist_funs": false,
        "hoist_props": true,
        "hoist_vars": false,
        "if_return": true,
        "join_vars": true,
        "keep_classnames": false,
        "keep_fargs": true,
        "keep_fnames": false,
        "keep_infinity": false,
        "loops": true,
        "negate_iife": true,
        "properties": true,
        "reduce_funcs": false,
        "reduce_vars": false,
        "side_effects": true,
        "switches": true,
        "typeofs": true,
        "unsafe": false,
        "unsafe_arrows": false,
        "unsafe_comps": false,
        "unsafe_Function": false,
        "unsafe_math": false,
        "unsafe_symbols": false,
        "unsafe_methods": false,
        "unsafe_proto": false,
        "unsafe_regexp": false,
        "unsafe_undefined": false,
        "unused": true,
        "const_to_let": true,
        "pristine_globals": true
      },
      "mangle": true
    }
  }
}

13. Real-World Example

Library build with SWC:

// swc.config.js
module.exports = {
  jsc: {
    parser: {
      syntax: 'typescript',
      tsx: true,
      decorators: true
    },
    transform: {
      react: {
        runtime: 'automatic'
      }
    },
    target: 'es2020',
    loose: false,
    externalHelpers: false,
    keepClassNames: false,
    minify: {
      compress: {
        unused: true
      },
      mangle: true
    }
  },
  module: {
    type: 'es6',
    strict: false,
    strictMode: true,
    lazy: false,
    noInterop: false
  },
  minify: process.env.NODE_ENV === 'production',
  sourceMaps: true
};
// package.json
{
  "scripts": {
    "build:esm": "swc src -d dist/esm --config-file swc.config.js",
    "build:cjs": "swc src -d dist/cjs --config-file swc.cjs.config.js",
    "build": "npm run build:esm && npm run build:cjs"
  }
}

14. Performance Tips

1. Use Parallel Compilation

SWC automatically uses all CPU cores.

2. Enable Caching

{
  "jsc": {
    "experimental": {
      "cacheRoot": ".swc"
    }
  }
}

3. Optimize Target

{
  "jsc": {
    "target": "es2020" // Don't transpile more than needed
  },
  "env": {
    "targets": "> 0.5%, last 2 versions, not dead"
  }
}

15. Migration from Babel

Step 1: Install SWC

npm uninstall babel-loader @babel/core @babel/preset-env
npm install --save-dev swc-loader

Step 2: Convert Config

Babel:

// .babelrc
{
  "presets": [
    ["@babel/preset-env", { "targets": "defaults" }],
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}

SWC:

// .swcrc
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true
    },
    "transform": {
      "react": {
        "runtime": "automatic"
      }
    },
    "target": "es2015"
  }
}

Step 3: Update Webpack

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.[jt]sx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'swc-loader'
        }
      }
    ]
  }
};

Summary

SWC revolutionizes JavaScript compilation:

  • 20-70x faster than Babel
  • Written in Rust for native performance
  • Drop-in replacement for Babel
  • Powers Next.js and Parcel
  • Active development with rapid improvements

Key Takeaways:

  1. 20x faster than Babel
  2. Supports TypeScript, JSX, decorators
  3. Built-in minification
  4. Easy migration from Babel
  5. Used by major frameworks

Next Steps:

Resources: