Awesome
TypeScript runtime comparisons
Comparison of Node.js TypeScript runtimes.
Disclaimer: This comparison is by the author & maintainer of tsx
Compared runtimes
<!-- runtimes:start --> <!-- runtimes:end -->Methodology
-
Tested on Node.js v12.20.0 because they all support it, and the
node:
prefix is not supported inrequire()
-
Tested in both package types
commonjs
&module
when applicable
Symbols
Symbol | Description |
---|---|
✅ | Pass (Sometimes clickable) |
❌ | Fail |
<span title="Example error message">⛔️</span> | Error (Hover to see error message) |
Project stats
<!-- projectStats:start -->tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
npm downloads | |||||||
Install size | |||||||
GitHub stars | |||||||
Issues open | |||||||
Issues closed | |||||||
Last commit |
Transformation
Supported transformation features and code tranformation correctness.
<!-- transformCommonjs:start -->Package type: CommonJS
tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
TypeScript syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
ESM → CJS: import/export syntax | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
ESM → CJS: import.meta.url shim | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
CJS scope in .js file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
CJS scope in .ts file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
CJS scope in .cjs file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
CJS scope in .cts file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
No CJS scope in .mjs file | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
No CJS scope in .mts file | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
Source maps | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
Package type: Module
tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
TypeScript syntax | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/ts.ts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/ts.ts">⛔️</span> | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/ts.ts">⛔️</span> | ✅ | ✅ |
CJS scope in .cjs file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
CJS scope in .cts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-module/transformation/cjs-scope.cts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-module/transformation/cjs-scope.cts">⛔️</span> | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-module/transformation/cjs-scope.cts">⛔️</span> | ✅ | ❌ |
No CJS scope in .js file | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
No CJS scope in .ts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/cjs-scope.ts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/cjs-scope.ts">⛔️</span> | ❌ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/cjs-scope.ts">⛔️</span> | ✅ | ✅ |
No CJS scope in .mjs file | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
No CJS scope in .mts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-module/transformation/cjs-scope.mts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-module/transformation/cjs-scope.mts">⛔️</span> | ❌ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-module/transformation/cjs-scope.mts">⛔️</span> | ✅ | ✅ |
Source maps | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/source-maps.ts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/source-maps.ts">⛔️</span> | ❌ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/transformation/source-maps.ts">⛔️</span> | ✅ | ✅ |
* CommonJS scope (CJS scope) refers to having the following variables available in the module scope: module
, exports
, require
, __filename
, __dirname
.
Resolution
Whether require()
/import()
can resolve a given specifier.
require()
tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
.ts file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
.ts file via .js | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
.ts file without extension | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
index.ts file via directory | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
.cts file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
.cts file via .cjs | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
.mts file | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
.mts file via .mjs | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
node: prefix | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
tsconfig.json paths | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
import()
tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
.ts file | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
.ts file via .js | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
.ts file without extension | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
index.ts file via directory | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
.cts file | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
.cts file via .cjs | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
.mts file | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
.mts file via .mjs | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
tsconfig.json paths | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
Interoperability
Whether it can correctly load a file for interoperability.
<!-- interopCommonjs:start -->Package type: CommonJS
tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
require() .js file (ESM export) | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | ✅ | ✅ | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> |
require() .ts file (ESM export) | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | ✅ | ✅ | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> |
require() .cjs file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
require() .cts file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
require() .mjs file | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | ✅ | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-commonjs/interops/mjs.mjs">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-commonjs/interops/mjs.mjs">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: require() of ES Module ./package-commonjs/interops/mjs.mjs not supported.">⛔️</span> |
require() .mts file | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-commonjs/interops/mts.mts">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> |
import() .js file (ESM export) | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ❌ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | ❌ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> |
import() .ts file (ESM export) | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-commonjs/interops/ts.ts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-commonjs/interops/ts.ts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-commonjs/interops/ts.ts">⛔️</span> | ✅ | ❌ | ✅ |
import() .cjs file | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
import() .cts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-commonjs/interops/cts.cts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-commonjs/interops/cts.cts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-commonjs/interops/cts.cts">⛔️</span> | ❌ | ✅ | ✅ |
import() .mjs file | ✅ | ✅ | ✅ | ✅ | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-commonjs/interops/mjs.mjs">⛔️</span> | ✅ | ✅ |
import() .mts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-commonjs/interops/mts.mts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-commonjs/interops/mts.mts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-commonjs/interops/mts.mts">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | ✅ |
Package type: Module
tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
require() .js file (ESM export) | ✅ | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/esm.js">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/esm.js">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/esm.js">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/esm.js">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/esm.js">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: require() of ES Module ./package-module/interops/esm.js from /Users/osame/Documents/public-github/privatenumber/ts-runtime-comparison/package-module/require-log.js not supported.">⛔️</span> |
require() .ts file (ESM export) | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/ts.ts">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> |
require() .cjs file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
require() .cts file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
require() .mjs file | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | ✅ | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/mjs.mjs">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/mjs.mjs">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/mjs.mjs">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: require() of ES Module ./package-module/interops/mjs.mjs not supported.">⛔️</span> |
require() .mts file | ✅ | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> | <span title="Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./package-module/interops/mts.mts">⛔️</span> | <span title="SyntaxError: Unexpected token 'export'">⛔️</span> |
import() .js file (ESM export) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
import() .ts file (ESM export) | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/interops/ts.ts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/interops/ts.ts">⛔️</span> | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.ts' for ./package-module/interops/ts.ts">⛔️</span> | ✅ | ✅ |
import() .cjs file | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
import() .cts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-module/interops/cts.cts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-module/interops/cts.cts">⛔️</span> | ❌ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.cts' for ./package-module/interops/cts.cts">⛔️</span> | ✅ | ✅ |
import() .mjs file | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
import() .mts file | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-module/interops/mts.mts">⛔️</span> | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-module/interops/mts.mts">⛔️</span> | ✅ | <span title="TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension '.mts' for ./package-module/interops/mts.mts">⛔️</span> | ✅ | ✅ |
Performance features
<!-- performance:start -->tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
Compiler | esbuild | SWC | esbuild | Babel | Sucrase (Babel fork) | TypeScript / SWC | esbuild |
Disk cache | ✅ <sup>?</sup> | ❌ | ✅ <sup>?</sup> | ✅ <sup>?</sup> | ❌ | ❌ <sup>?</sup> | ❌ |
DX features
<!-- dx:start -->tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
TypeScript REPL | ✅ <sup>?</sup> | ❌ | ❌ | ❌ | ❌ | ✅ <sup>?</sup> | ❌ |
Watch mode | ✅ <sup>?</sup> | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
Type checking | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
Hides experimental feature warnings | ✅ | - | - | - | - | ✅ <sup>?</sup> | ❌ |
Binaries | tsx | swc-node | esr | jiti | sucrase-node | ts-node, ts-node-esm, +4 | tsm |
Testing
<!-- testing:start -->tsx | @swc/register | esbuild-runner | jiti | sucrase | ts-node | tsm | |
---|---|---|---|---|---|---|---|
Operating systems | Linux & Windows | Linux | No tests | Linux & Windows | Linux | Linux & Windows | Linux & Windows |
Node.js versions | 12.20 ~ 18 | Latest LTS | No tests | 16 | 14 & 16 | 12 ~ 18 + Nightly | 12.22.10 ~ 16.14 |