SWC Node.js CLI
swc-node is a command-line interface (CLI) wrapper for `@swc-node/register`, a high-performance TypeScript and JavaScript transpiler designed for Node.js environments. While the `swc-node` package itself is at version `1.0.0` and has not seen recent updates (last published over four years ago), its core dependency, `@swc-node/register`, is actively developed, with its latest stable version being `1.11.0`. This library leverages SWC (Speedy Web Compiler), a Rust-based tool, to provide significantly faster compilation of TypeScript and modern JavaScript to a compatible target, often serving as a performant alternative to `ts-node` for development workflows. It focuses purely on transpilation without performing type checking, making it ideal for environments where build speed is prioritized and type checking is handled by a separate process (e.g., `tsc`). It supports both CommonJS via a `require` hook and ES Modules using Node.js's `--import` flag. Key differentiators include its Rust-native speed, minimal overhead, and `tsconfig.json` compatibility for transpilation options.
Common errors
-
Failed to load SWC binary for {platform}/{arch} (Bindings not found)cause SWC relies on native Rust binaries; this error indicates a failure to locate or load the correct binary for your system's architecture or operating system, often due to Node.js version/architecture mismatch or missing C++ runtime libraries on Windows.fixVerify your Node.js installation (e.g., `node -p "process.arch"`) matches your OS architecture. On Windows, install the Microsoft Visual C++ Redistributables. If using npm, try `npm cache clean --force` then `rm -rf node_modules package-lock.json` and `npm install` again to force a fresh download of optional platform-specific binaries. -
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for {file_path}cause This typically occurs in ES Module contexts when Node.js encounters a `.ts` file without a registered loader, or when the ESM loader for `@swc-node/register` isn't correctly configured or loaded.fixEnsure your `package.json` has `"type": "module"`. Use the command `node --import @swc-node/register/esm-register your-script.ts`. If using a test runner, verify its configuration for ESM and the SWC register hook. Update `@swc-node/register` to its latest version. -
error: Unexpected token Some(At) --> {file_path}:{line}:{column} | {line} | @DecoratorNamecause SWC's parser did not recognize a decorator, usually because decorator support is not enabled in the SWC configuration (typically in a `.swcrc` file or via options passed to `@swc-node/register`).fixIn your `.swcrc` configuration (or `jsc` options), ensure `jsc.parser.syntax` is `"typescript"` and `jsc.parser.decorators` is `true`. If using legacy decorators, also set `jsc.transform.legacyDecorator: true`. Also, verify `experimentalDecorators` and `emitDecoratorMetadata` are set in `tsconfig.json` if applicable. -
Error: Cannot find module '@swc-node/register'
cause The `@swc-node/register` package is not installed as a dependency in your project, or Node.js cannot resolve its path.fixRun `npm install @swc-node/register` or `yarn add @swc-node/register` to add it to your `devDependencies`. Ensure your `node -r` or `node --import` command correctly references the installed package.
Warnings
- deprecated The `swc-node` CLI package (version 1.0.0, last published over 4 years ago) is largely unmaintained. For the latest features, bug fixes, and better compatibility with modern Node.js and TypeScript versions, it is highly recommended to directly use the `@swc-node/register` package.
- gotcha SWC, and by extension `@swc-node/register`, performs *only* transpilation, not type checking. This means it will transform TypeScript code to JavaScript without validating types. Runtime errors due to type mismatches might occur if not caught by a separate `tsc --noEmit` step or IDE.
- gotcha Platform-specific `@swc/core` binaries are required. Issues can arise from Node.js architecture mismatches (32-bit vs. 64-bit), missing system dependencies (e.g., Microsoft Visual C++ Redistributables on Windows), or package manager issues with optional dependencies.
- gotcha Configuring decorators (e.g., `@Controller`) requires specific settings in `.swcrc` (e.g., `jsc.parser.decorators: true`) and/or `tsconfig.json` (e.g., `experimentalDecorators`, `emitDecoratorMetadata`, `useDefineForClassFields`). Incorrect configuration can lead to runtime errors or unexpected transpilation behavior.
- gotcha ES Module resolution and path aliases can be complex. Issues like `ERR_UNKNOWN_FILE_EXTENSION` or failure to resolve relative imports may occur when using `--import @swc-node/register/esm-register`, especially with older Node.js versions or specific testing frameworks like Mocha.
Install
-
npm install swc-node -
yarn add swc-node -
pnpm add swc-node
Imports
- CommonJS Register Hook
require('@swc-node/register'); // While technically correct, runtime registration via CLI flag is primary.node -r @swc-node/register your-script.ts
- ES Modules Register Hook
node -r @swc-node/register/esm-register your-module.ts // -r is for CJS, --import for ESM
node --import @swc-node/register/esm-register your-module.ts
- CLI Execution
node your-script.ts // Without transpilation, Node.js can't directly run TypeScript
npx swc-node your-script.ts
Quickstart
{
"name": "my-swc-project",
"version": "1.0.0",
"description": "A simple SWC project demonstrating swc-node usage",
"main": "src/index.ts",
"type": "module",
"scripts": {
"start": "npx swc-node src/index.ts",
"start-cjs": "node -r @swc-node/register src/index.ts",
"start-esm": "node --import @swc-node/register/esm-register src/index.ts"
},
"devDependencies": {
"swc-node": "^1.0.0",
"@swc-node/register": "^1.11.0",
"typescript": "^5.0.0"
}
}
// tsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"lib": ["es2020", "dom"],
"strict": true,
"esModuleInterop": true,
"isolatedModules": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"]
}
// src/index.ts
import { greet } from './util.js'; // Note .js extension for ESM resolution
console.log(greet('Developer'));
async function simulateAsyncCall() {
console.log('Starting async operation...');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Async operation complete!');
}
simulateAsyncCall();
// src/util.ts
export function greet(name: string): string {
return `Hello, ${name}! This message was transpiled by SWC.`;
}