Open-Source Wikis

/

Next.js

/

Packages

/

next-swc

vercel/next.js

next-swc

Purpose

@next/swc is the package that distributes the native binaries consumed by packages/next. It contains no real source code — it is a thin wrapper that downloads or builds the napi-rs binding produced from crates/next-napi-bindings. The Rust implementation of every SWC transform that Next.js applies (JSX import source, server actions, dynamic IO, next/font preloading, etc.) lives in crates/next-custom-transforms and is exposed through this package.

Source: packages/next-swc/. Backing crates: crates/next-napi-bindings/, crates/next-custom-transforms/, crates/wasm/.

Directory layout

packages/next-swc/
├── package.json
└── native/                # Built or downloaded .node binaries

The directory deliberately holds only the platform-specific binaries. The full binding API surface is generated from Rust by napi-rs.

How the binary gets there

Two paths produce packages/next-swc/native/*.node:

graph TD
    Install[pnpm install] --> Postinstall[scripts/install-native.mjs]
    Postinstall --> Has{Local node_modules<br/>has @next/swc?}
    Has -- yes --> Skip[skip]
    Has -- no --> Fetch[fetch published binary<br/>from npm]

    Build[pnpm swc-build-native] --> Cargo[cargo build --release<br/>-p next-napi-bindings]
    Cargo --> Move[scripts/build-native.ts<br/>moves .node into native/]

The scripts/install-native.mjs postinstall script picks the platform-correct binary from npm. For local development on transforms, pnpm swc-build-native rebuilds from source. After switching branches, delete packages/next-swc/native/*.node and re-install to pick up the npm-published binary again — a stale local build is a common cause of unexplained Turbopack errors.

Consumers

packages/next/src/build/swc/ loads the native binding. Two consumption modes:

  • Direct napi — Node.js callers via next-napi-bindings (the default).
  • WASM fallbackcrates/wasm/ produces a wasm-bindgen build for environments where the native binary cannot run (notably some serverless edges and StackBlitz).

Custom transforms

The actual transforms live at crates/next-custom-transforms/. Examples:

  • next/font resolution and preload injection
  • Server actions ('use server' directive plumbing)
  • Dynamic IO instrumentation
  • import.meta.url rewrites for static analysis
  • Page extensions normalization

Each transform is implemented as an SWC visitor pass and registered in the per-runtime config produced by crates/next-core/.

Targets

The published @next/swc package ships native binaries for these platforms (driven by scripts/publish-native.js and the release-next-rspack.yml and per-platform GitHub Actions workflows):

  • darwin-arm64, darwin-x64
  • linux-x64-gnu, linux-x64-musl, linux-arm64-gnu, linux-arm64-musl
  • win32-arm64-msvc, win32-x64-msvc
  • wasm (via crates/wasm)

Each platform has its own scoped npm package (@next/swc-darwin-arm64, etc.) that the user installs as an optional dependency through Next.js's optional-dependencies block.

Key source files

File Purpose
packages/next-swc/package.json Manifest pointing at platform-specific subpkgs
crates/next-napi-bindings/src/lib.rs napi-rs bindings (the entry the binary exposes)
crates/next-custom-transforms/src/lib.rs Visitor registration
crates/wasm/src/lib.rs wasm-bindgen wrapper
scripts/install-native.mjs Postinstall binary picker
scripts/build-native.ts Build script invoked by pnpm swc-build-native
scripts/publish-native.js Per-platform publish

The Rust side is documented under crates/:

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

next-swc – Next.js wiki | Factory