PackemExamplesTransformersswc

swc

Rust-powered compilation with swc

swc Transformer

The swc transformer is a Rust-powered alternative to esbuild with the most comprehensive transformation feature set. It is the best choice when you need decorators — both legacy (experimentalDecorators) and the modern stage 3 syntax.

Overview

This example shows how to build a library that uses decorators with the swc transformer. swc options are exposed through rollup.swc, including the full jsc (JavaScript compiler) configuration.

swc handles:

  • TypeScript and modern JavaScript transformation
  • Legacy and stage 3 decorators, with optional decorator metadata
  • JSX for React, Preact, and other runtimes
  • Minification

Packem automatically externalizes @swc/helpers when the swc transformer is active (swc emits imports from it with externalHelpers: true). Make sure @swc/helpers is available to consumers of your package.

When to Use

  • Projects using decorators (legacy or stage 3)
  • Code that relies on emitDecoratorMetadata (e.g. dependency injection frameworks)
  • Applications where build performance is critical and you want the broadest feature coverage

Project Setup

TypeScript Configuration

Decorator behavior is driven by your tsconfig.json. Packem reads these flags and configures swc accordingly:

{
  "compilerOptions": {
    "target": "ES2020",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Packem Configuration

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/swc'

export default defineConfig({
  transformer,
  rollup: {
    swc: {
      jsc: {
        // Keep original class names through the transform
        keepClassNames: true,
        parser: {
          syntax: 'typescript',
          // Enable legacy decorator parsing (mirrors experimentalDecorators)
          decorators: true
        },
        transform: {
          // Use the legacy (TypeScript) decorator implementation
          legacyDecorator: true,
          // Emit design:type metadata for reflection
          decoratorMetadata: true
        }
      }
    }
  }
})

Most of the jsc block is derived from your tsconfig automatically — parser.decorators follows experimentalDecorators, transform.legacyDecorator follows experimentalDecorators, and transform.decoratorMetadata follows emitDecoratorMetadata. The example above shows the keys explicitly so you can see what Packem configures; you only need to override them when you want different behavior.

Minimal Configuration

For projects without special requirements, the transformer alone is enough — Packem applies sensible swc defaults from your tsconfig:

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/swc'

export default defineConfig({
  transformer
})

Building

packem build

Notes

  • swc options are a jsc-based configuration object passed via rollup.swc; the configFile, filename, and swcrc keys are managed by Packem and cannot be set.
  • By default Packem enables jsc.externalHelpers, jsc.keepClassNames, and jsc.loose, and sets the React/JSX options from your tsconfig.
  • sourceMaps is controlled by the top-level sourcemap option and passed through to swc.
  • Minification is wired to the top-level minify option.
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues