Open-source project
swc-project/swc-node avatar
swc-project/swc-node

swc-node: A Faster TypeScript Runtime Hook Without the Typecheck

Faster ts-node without typecheck. Detail: @swc-node/core Benchmark transform RxJS AjaxObservable.ts to ES2015 & CommonJS JavaScript.

1,981 stars95 forksTypeScriptMIT

At a glance

What is it?
swc-node is a set of packages that let Node run TypeScript files directly by using the SWC compiler instead of the TypeScript compiler. It targets developers who want speed and are willing to skip type checking during execution.
Who is it for?
Adopt swc-node if you need to run TypeScript directly in Node or Jest and you are comfortable skipping type checking at runtime. Do not use it if your workflow depends on type errors being caught during execution, since swc-node does not typecheck.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem: TypeScript Execution Overhead

The README explicitly states that swc-node is a 'Faster ts-node without typecheck'. That is the entire promise. If you need type errors to appear when you run a script, this tool is not for you. But if you are tired of waiting for ts-node to re-check types every time you run a test, swc-node offers a different trade-off.

How swc-node Works: SWC as the Transform Engine

swc-node is not a single tool but a collection of packages. The core package, @swc-node/core, is described as the 'Fastest TypeScript transformer'. It uses the SWC compiler, which is written in Rust and compiled to native code. This is why the README claims there is no node-gyp and no postinstall script. SWC is distributed as prebuilt binaries, so installing @swc-node/core does not require compiling native modules on the user's machine. The register package, @swc-node/register, hooks into Node's module loading system. For CommonJS, you use node -r @swc-node/register script.ts. For ESM, the README shows different commands depending on your Node version: node --import @swc-node/register/esm-register for Node >= 22.15, node --import @swc-node/register/esm-register for Node >= 20.6, and a deprecated --loader flag for Node <= 20.5. The register package intercepts require or import calls and transforms TypeScript files on the fly, using SWC to strip types and transpile to JavaScript. The transform can be done synchronously or in parallel, as shown in the benchmark section.

Getting Started: Commands and Configuration

The README gives concrete commands for using @swc-node/register. The basic CommonJS usage is: npm i -D @swc-node/register, then node -r @swc-node/register script.ts. For ESM projects, you need to pass --enable-source-maps to node, and use one of the esm-register variants. The README also shows a shebang line: #!/usr/bin/env -S node --import @swc-node/register/esm-register. If you want to ignore tsconfig.json, you can set TS_NODE_PROJECT=null. For projects that use a .swcrc file, you can set the environment variable SWCRC=true. The register package is a drop-in replacement for ts-node/register/transpile-only, so existing scripts that use ts-node with transpile-only should be able to switch by changing the require or import path. The @swc-node/jest package is used as a Jest transformer, replacing ts-jest. The README shows that it can be configured in Jest's transform option, though it does not give the exact configuration snippet in the provided text.

Benchmarks: What the Numbers Show and What They Don't

The README includes benchmark results for transforming RxJS AjaxObservable.ts to ES2015 and CommonJS. On a 2018 MacBook Pro, the synchronous transform shows esbuild at 510 ops/sec, @swc-node/core at 438 ops/sec, typescript at 28.83 ops/sec, and babel at 24.21 ops/sec. In this case, esbuild is fastest. However, in the parallel transform benchmark, @swc-node/core beats esbuild: 1,253 ops/sec versus 914 ops/sec with UV_THREADPOOL_SIZE=11, and 1,123 ops/sec versus 847 ops/sec without that setting. So the performance advantage depends on whether you use the parallel API. The README also includes a Jest benchmark comparing ts-jest with isolatedModules: true against @swc-node/jest. The test suite time drops from 54.631 seconds to 10.511 seconds. These numbers are specific to the given hardware and test suite. They are not a guarantee for your project. The benchmark code is in the bench directory, so you can run it yourself if you want to verify.

Limitations and Failure Modes: No Type Checking and ESM Complexity

The most obvious limitation is that swc-node does not type check. The README says 'without typecheck' in the description. That means type errors will not be caught at runtime. If you rely on ts-node to catch type errors during development, you will lose that safety net. Another limitation is the ESM support. The README shows different commands for different Node versions, and the --loader approach is deprecated. This indicates that ESM support is evolving and may be fragile. If you are on an older Node version, you might need to use the deprecated loader, which could break in future Node releases. Also, SWC is not a full TypeScript compiler. It does not support all TypeScript features, especially some experimental decorators or certain tsconfig options. The README does not list which features are unsupported, but you should verify your codebase before adopting. Finally, the benchmark shows that esbuild is faster in the synchronous case, so if you only need a one-off transform, esbuild might be a better choice.

Alternatives: esbuild and ts-node

The README directly compares swc-node to esbuild and ts-node. esbuild is a JavaScript bundler that also transforms TypeScript. It is faster in the synchronous benchmark but slower in the parallel benchmark. The key difference is that esbuild is a bundler, while swc-node is designed as a runtime hook. If you need to run a single TypeScript file without a build step, swc-node's register package is more direct. ts-node is the incumbent. It uses the TypeScript compiler, so it can type check if you want it to. ts-node with transpile-only mode disables type checking, but it still uses the TypeScript compiler for transpilation, which is slower than SWC. The README positions @swc-node/register as a 'Faster ts-node/register/transpile-only alternative'. If you need type checking during execution, ts-node is the right tool. If you do not, swc-node offers a speed advantage, as shown in the benchmarks.

Maintenance and License Considerations

The repository is under the MIT license, which is permissive and allows commercial use. The last push to the master branch was on 2026-07-16, and the most recent release is @swc-node/core@1.15.0 from the same date. However, the @swc-node/register package has not had a release since 2024-07-17. That gap might indicate that the register package is stable, or it might mean that maintenance is focused on the core package. The README does not mention a maintenance policy or upgrade cost. Since swc-node is part of the swc-project organization, it benefits from the broader SWC ecosystem, but it is a separate project. When upgrading, you should check the changelog for each package, as the ESM loader changes could affect your setup. The license implies you can use it freely, but you should read the full license text for any specific obligations.

Editorial conclusion

Adopt swc-node if you need to run TypeScript directly in Node or Jest and you are comfortable skipping type checking at runtime. Do not use it if your workflow depends on type errors being caught during execution, since swc-node does not typecheck. Before adopting, verify that your tsconfig options are supported by SWC, especially experimental decorators and other non-standard syntax, and confirm that your Node version matches the required ESM loader or import hook. Run the benchmark in your own environment, as the README's numbers come from a specific 2018 MacBook Pro and may not reflect your setup.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
Community notes

Community notes