├── .node-version
├── packages
├── core
│ ├── .gitignore
│ ├── browser.js
│ ├── README.md
│ ├── tsconfig.json
│ ├── esm.mjs
│ ├── wasi-worker-browser.mjs
│ ├── register.mjs
│ ├── reexport-oxc-runtime.mjs
│ ├── wasi-worker.mjs
│ ├── oxc-node.wasi-browser.js
│ ├── index.d.ts
│ ├── oxc-node.wasi.cjs
│ ├── CHANGELOG.md
│ ├── index.js
│ └── package.json
├── condition-dev
│ ├── condition-dev.ts
│ ├── condition-node.mjs
│ ├── condition-require.cjs
│ └── package.json
├── integrate-module-bundler
│ ├── src
│ │ ├── common.d.cts
│ │ ├── common.cjs
│ │ ├── typescript-cjs
│ │ │ ├── index.ts
│ │ │ └── package.json
│ │ ├── foo.ts
│ │ ├── enforce-mts
│ │ │ ├── package.json
│ │ │ └── index.mts
│ │ ├── subdirectory
│ │ │ ├── bar.ts
│ │ │ ├── baz.ts
│ │ │ └── index.ts
│ │ ├── compiled.d.ts
│ │ ├── component.tsx
│ │ ├── compiled.js
│ │ ├── babel-generated-double-default
│ │ │ ├── index.d.ts
│ │ │ ├── package.json
│ │ │ └── index.js
│ │ ├── nestjs
│ │ │ ├── config.ts
│ │ │ ├── index.ts
│ │ │ ├── app.controller.ts
│ │ │ ├── app.module.ts
│ │ │ └── app.service.ts
│ │ ├── js-module.js
│ │ └── index.ts
│ ├── tsconfig.json
│ └── package.json
├── integrate-module
│ ├── src
│ │ ├── foo.mts
│ │ ├── subdirectory
│ │ │ ├── bar.mts
│ │ │ ├── baz.mts
│ │ │ └── index.mts
│ │ ├── compiled.d.ts
│ │ ├── component.tsx
│ │ ├── compiled.js
│ │ ├── js-module.mjs
│ │ └── index.ts
│ ├── tsconfig.json
│ └── package.json
├── integrate-ava
│ ├── __tests__
│ │ ├── fixtures
│ │ │ ├── source-map-fixture.ts
│ │ │ ├── stacktrace-esm.mts
│ │ │ ├── stacktrace-esm.ts
│ │ │ └── stacktrace-cjs.cts
│ │ ├── index.spec.ts
│ │ └── cli.spec.ts
│ ├── tsconfig.json
│ └── package.json
├── bench
│ ├── tsconfig.json
│ ├── package.json
│ └── index.ts
└── cli
│ ├── tsconfig.json
│ ├── rolldown.config.js
│ ├── README.md
│ ├── package.json
│ ├── src
│ └── index.ts
│ └── CHANGELOG.md
├── .husky
└── pre-commit
├── .github
├── FUNDING.yml
├── renovate.json
└── workflows
│ ├── zizmor.yml
│ ├── autofix.yml
│ └── CI.yml
├── .oxfmtrc.json
├── rust-toolchain.toml
├── pnpm-workspace.yaml
├── .editorconfig
├── lerna.json
├── justfile
├── tsconfig.json
├── .gitattributes
├── README.md
├── package.json
├── .cargo
└── config.toml
├── Cargo.toml
├── .gitignore
├── CHANGELOG.md
└── src
└── lib.rs
/.node-version:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/packages/core/.gitignore:
--------------------------------------------------------------------------------
1 | src
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | pnpm lint-staged
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [Brooooooklyn, Boshen]
2 |
--------------------------------------------------------------------------------
/.oxfmtrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignorePatterns": ["pnpm-lock.yaml"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/core/browser.js:
--------------------------------------------------------------------------------
1 | export * from "@oxc-node/core-wasm32-wasi";
2 |
--------------------------------------------------------------------------------
/packages/condition-dev/condition-dev.ts:
--------------------------------------------------------------------------------
1 | export const condition = "dev";
2 |
--------------------------------------------------------------------------------
/packages/condition-dev/condition-node.mjs:
--------------------------------------------------------------------------------
1 | export const condition = "node";
2 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/common.d.cts:
--------------------------------------------------------------------------------
1 | export const common: string;
2 |
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | channel = "1.92.0"
3 | profile = "default"
4 |
--------------------------------------------------------------------------------
/packages/condition-dev/condition-require.cjs:
--------------------------------------------------------------------------------
1 | module.exports.condition = "require";
2 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/common.cjs:
--------------------------------------------------------------------------------
1 | module.exports.common = "common";
2 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/typescript-cjs/index.ts:
--------------------------------------------------------------------------------
1 | export const foo = "foo";
2 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/foo.mts:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return "foo";
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/foo.ts:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return "foo";
3 | }
4 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - packages/*
3 |
4 | catalog:
5 | "@napi-rs/cli": 3.5.0
6 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/enforce-mts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "commonjs"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/typescript-cjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "commonjs"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/subdirectory/bar.mts:
--------------------------------------------------------------------------------
1 | export function bar() {
2 | return "bar";
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/subdirectory/baz.mts:
--------------------------------------------------------------------------------
1 | export function baz() {
2 | return "baz";
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/enforce-mts/index.mts:
--------------------------------------------------------------------------------
1 | export const exportFromMts = "exportFromMts";
2 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/subdirectory/bar.ts:
--------------------------------------------------------------------------------
1 | export function bar() {
2 | return "bar";
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/subdirectory/baz.ts:
--------------------------------------------------------------------------------
1 | export function baz() {
2 | return "baz";
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/compiled.d.ts:
--------------------------------------------------------------------------------
1 | export declare class CompiledClass {
2 | name: string;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/compiled.d.ts:
--------------------------------------------------------------------------------
1 | export declare class CompiledClass {
2 | name: string;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/component.tsx:
--------------------------------------------------------------------------------
1 | export function Component() {
2 | return
Component
;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/component.tsx:
--------------------------------------------------------------------------------
1 | export function Component() {
2 | return Component
;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/compiled.js:
--------------------------------------------------------------------------------
1 | export class CompiledClass {
2 | constructor() {
3 | this.name = "CompiledClass";
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/subdirectory/index.ts:
--------------------------------------------------------------------------------
1 | export { baz } from "./baz";
2 | export function module() {
3 | return "module";
4 | }
5 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/subdirectory/index.mts:
--------------------------------------------------------------------------------
1 | export { baz } from "./baz.mjs";
2 | export function module() {
3 | return "module";
4 | }
5 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/compiled.js:
--------------------------------------------------------------------------------
1 | export class CompiledClass {
2 | constructor() {
3 | this.name = "CompiledClass";
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/babel-generated-double-default/index.d.ts:
--------------------------------------------------------------------------------
1 | declare const exports: {
2 | default: () => string;
3 | };
4 |
5 | export default exports;
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 |
7 | [*.{js,json,yml}]
8 | charset = utf-8
9 | indent_style = space
10 | indent_size = 2
11 |
--------------------------------------------------------------------------------
/packages/core/README.md:
--------------------------------------------------------------------------------
1 | # `@oxc-node/core`
2 |
3 | Transformer and register for Node.js projects.
4 |
5 | ## Usage
6 |
7 | ```bash
8 | node --import @oxc-node/core/register ./path/to/entry.ts
9 | ```
10 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/babel-generated-double-default/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "problematic cjs file type generated by babel",
3 | "main": "./index.js",
4 | "types": "./index.d.ts"
5 | }
6 |
--------------------------------------------------------------------------------
/packages/integrate-ava/__tests__/fixtures/source-map-fixture.ts:
--------------------------------------------------------------------------------
1 | export function example(value: number): number {
2 | if (value < 0) {
3 | throw new Error("negative value");
4 | }
5 |
6 | return value * 2;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/nestjs/config.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 |
3 | @Injectable()
4 | export class ConfigService {
5 | public readonly server = {
6 | port: 3000,
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/packages/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "outDir": "./dist"
6 | },
7 | "files": ["./index.d.ts"],
8 | "exclude": ["__tests__", "./dist"]
9 | }
10 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json",
3 | "version": "0.0.35",
4 | "packages": ["packages/*"],
5 | "npmClient": "pnpm",
6 | "skipNxCache": true,
7 | "signGitCommit": true,
8 | "signGitTag": true,
9 | "private": false
10 | }
11 |
--------------------------------------------------------------------------------
/packages/integrate-ava/__tests__/fixtures/stacktrace-esm.mts:
--------------------------------------------------------------------------------
1 | import assert from "node:assert/strict";
2 | import { describe, it } from "node:test";
3 |
4 | describe("stacktrace esm mts", () => {
5 | it("should preserve stack trace", () => {
6 | assert.ok(false);
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/packages/integrate-ava/__tests__/fixtures/stacktrace-esm.ts:
--------------------------------------------------------------------------------
1 | import assert from "node:assert/strict";
2 | import { describe, it } from "node:test";
3 |
4 | describe("stacktrace esm ts", () => {
5 | it("should preserve stack trace", () => {
6 | assert.ok(false);
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/packages/integrate-ava/__tests__/fixtures/stacktrace-cjs.cts:
--------------------------------------------------------------------------------
1 | const { describe, it } = require("node:test");
2 | const assert = require("node:assert/strict");
3 |
4 | describe("stacktrace cts", () => {
5 | it("should preserve stack trace", () => {
6 | assert.ok(false);
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/packages/bench/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "composite": true,
6 | "module": "NodeNext",
7 | "moduleResolution": "NodeNext"
8 | },
9 | "include": ["index.ts"],
10 | "exclude": ["dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/condition-dev/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "condition-dev",
3 | "private": true,
4 | "type": "module",
5 | "exports": {
6 | ".": {
7 | "dev": "./condition-dev.ts",
8 | "node": "./condition-node.mjs",
9 | "require": "./condition-require.cjs"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "composite": true,
5 | "outDir": "./dist",
6 | "rootDir": "./src",
7 | "resolveJsonModule": true
8 | },
9 | "include": ["package.json", "./src"],
10 | "exclude": ["__tests__", "./dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | _default:
2 | @just --list -u
3 |
4 | alias r := ready
5 |
6 | ready:
7 | just build
8 | just test
9 |
10 | build:
11 | pnpm --filter @oxc-node/core build
12 | pnpm --filter @oxc-node/core export-oxc-runtime
13 | pnpm --filter @oxc-node/cli build
14 | pnpm install
15 |
16 | test:
17 | pnpm test
18 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/nestjs/index.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory } from "@nestjs/core";
2 |
3 | import { AppModule } from "./app.module";
4 |
5 | export async function bootstrap() {
6 | const app = await NestFactory.create(AppModule);
7 | await app.listen(3000);
8 | return { app, [Symbol.asyncDispose]: async () => app.close() };
9 | }
10 |
--------------------------------------------------------------------------------
/packages/integrate-ava/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib",
5 | "composite": true,
6 | "module": "ESNext",
7 | "moduleResolution": "Bundler"
8 | },
9 | "include": ["__tests__/**/*.ts"],
10 | "exclude": ["__tests__/fixtures/**/*"],
11 | "references": [{ "path": "../core" }]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/integrate-ava/__tests__/index.spec.ts:
--------------------------------------------------------------------------------
1 | import { OxcTransformer } from "@oxc-node/core";
2 | import test from "ava";
3 |
4 | test("transform", async (t) => {
5 | const transformer = new OxcTransformer(process.cwd());
6 | const result = await transformer.transformAsync("foo.ts", "const foo: number = 1");
7 | t.is(result.source(), '"use strict";\nconst foo = 1;\n');
8 | });
9 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/nestjs/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get } from "@nestjs/common";
2 | import { AppService } from "./app.service";
3 |
4 | @Controller()
5 | export class AppController {
6 | constructor(public readonly appService: AppService) {}
7 |
8 | @Get()
9 | getHello(): string {
10 | return this.appService.getHello();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/nestjs/app.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from "@nestjs/common";
2 |
3 | import { AppController } from "./app.controller";
4 | import { AppService } from "./app.service";
5 | import { ConfigService } from "./config";
6 |
7 | @Module({
8 | imports: [],
9 | controllers: [AppController],
10 | providers: [AppService, ConfigService],
11 | })
12 | export class AppModule {}
13 |
--------------------------------------------------------------------------------
/packages/integrate-module/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "target": "ESNext",
5 | "composite": true,
6 | "jsx": "react-jsx",
7 | "outDir": "dist",
8 | "resolveJsonModule": true,
9 | "baseUrl": "./",
10 | "paths": {
11 | "@subdirectory/*": ["./src/subdirectory/*"]
12 | }
13 | },
14 | "include": ["src", "package.json"]
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bench/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bench",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "bench": "oxnode index.ts"
8 | },
9 | "devDependencies": {
10 | "@oxc-node/cli": "workspace:*",
11 | "@swc/core": "^1.13.2",
12 | "esbuild": "^0.27.0",
13 | "rxjs": "^7.8.2",
14 | "tinybench": "^6.0.0",
15 | "typescript": "^5.8.3"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": ["github>Boshen/renovate", "helpers:pinGitHubActionDigestsToSemver"],
4 | "packageRules": [
5 | {
6 | "matchManagers": ["cargo", "npm"],
7 | "matchDepNames": ["oxc", "oxc_resolver", "@oxc-project/runtime"],
8 | "groupName": "oxc",
9 | "schedule": ["at any time"]
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/cli/rolldown.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "rolldown";
2 |
3 | export default defineConfig({
4 | input: "./src/index.ts",
5 | resolve: {
6 | conditionNames: ["module", "node"],
7 | mainFields: ["module", "main"],
8 | },
9 | platform: "node",
10 | external: ["@oxc-node/core"],
11 | treeshake: true,
12 | output: {
13 | format: "esm",
14 | assetFileNames: "[name].js",
15 | },
16 | });
17 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/nestjs/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 |
3 | import { ConfigService } from "./config";
4 |
5 | @Injectable()
6 | export class AppService {
7 | public readonly websocket = {
8 | port: this.config.server.port + 1,
9 | };
10 |
11 | constructor(private readonly config: ConfigService) {}
12 |
13 | getHello(): string {
14 | return "Hello World!";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "target": "ESNext",
5 | "moduleResolution": "NodeNext",
6 | "module": "NodeNext"
7 | },
8 | "references": [
9 | {
10 | "path": "./packages/cli"
11 | },
12 | {
13 | "path": "./packages/core"
14 | },
15 | {
16 | "path": "./packages/integrate-module"
17 | },
18 | {
19 | "path": "./packages/integrate-module-bundler"
20 | }
21 | ],
22 | "include": []
23 | }
24 |
--------------------------------------------------------------------------------
/packages/cli/README.md:
--------------------------------------------------------------------------------
1 | # `@oxc-node/cli`
2 |
3 | CLI tool for `oxc-node`.
4 |
5 | ## Features
6 |
7 | - Run a script with oxc transformer and oxc-resolver
8 | - Support run TypeScript without any configuration
9 | - Support ESM and CJS
10 | - Support source map
11 |
12 | ## Installation
13 |
14 | Install globally, you can use it replace `node` command anywhere.
15 |
16 | ```bash
17 | npm install @oxc-node/cli -g
18 | ```
19 |
20 | ## Usage
21 |
22 | ```bash
23 | oxnode ./path/to/index.ts
24 | ```
25 |
--------------------------------------------------------------------------------
/packages/integrate-ava/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "integrate-ava",
3 | "private": true,
4 | "type": "module",
5 | "scripts": {
6 | "test": "ava"
7 | },
8 | "devDependencies": {
9 | "@oxc-node/core": "workspace:*",
10 | "ava": "^6.4.1"
11 | },
12 | "ava": {
13 | "cache": false,
14 | "extensions": {
15 | "ts": "module"
16 | },
17 | "files": [
18 | "__tests__/**/*.spec.ts"
19 | ],
20 | "nodeArguments": [
21 | "--import",
22 | "@oxc-node/core/register"
23 | ],
24 | "timeout": "1m"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | "moduleResolution": "Bundler",
7 | "allowJs": true,
8 | "composite": true,
9 | "jsx": "react-jsx",
10 | "outDir": "dist",
11 | "experimentalDecorators": true,
12 | "emitDecoratorMetadata": true,
13 | "useDefineForClassFields": false,
14 | "baseUrl": "./",
15 | "paths": {
16 | "@subdirectory/*": ["./src/subdirectory/*"]
17 | }
18 | },
19 | "include": ["src", "package.json"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/core/esm.mjs:
--------------------------------------------------------------------------------
1 | import { isMainThread, MessageChannel } from "node:worker_threads";
2 |
3 | import { createResolve, initTracing, load } from "./index.js";
4 |
5 | initTracing();
6 |
7 | if (!isMainThread) {
8 | const mc = new MessageChannel();
9 | mc.port1.ref();
10 | }
11 |
12 | /**
13 | * @type {import('node:module').ResolveHook}
14 | */
15 | function resolve(specifier, context, nextResolve) {
16 | return createResolve(
17 | {
18 | getCurrentDirectory: () => process.cwd(),
19 | },
20 | specifier,
21 | context,
22 | nextResolve,
23 | );
24 | }
25 |
26 | export { load, resolve };
27 |
--------------------------------------------------------------------------------
/packages/integrate-module/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "integrate-module",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "test": "oxnode ./src/index.ts"
8 | },
9 | "dependencies": {
10 | "file-type": "^21.0.0",
11 | "p-timeout": "^7.0.0"
12 | },
13 | "devDependencies": {
14 | "@napi-rs/tar": "^1.0.0",
15 | "@napi-rs/wasm-runtime": "^1.0.1",
16 | "@oxc-node/cli": "workspace:*",
17 | "@types/node": "^25.0.0",
18 | "@types/react": "^19.1.8",
19 | "@types/react-dom": "^19.1.6",
20 | "canvaskit-wasm": "^0.40.0",
21 | "ipaddr.js": "^2.2.0",
22 | "postgres": "^3.4.7",
23 | "react": "^19.1.0",
24 | "react-dom": "^19.1.0",
25 | "simple-git": "^3.28.0",
26 | "ts-node": "^10.9.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 |
5 | *.ts text eol=lf merge=union
6 | *.tsx text eol=lf merge=union
7 | *.rs text eol=lf merge=union
8 | *.js text eol=lf merge=union
9 | *.json text eol=lf merge=union
10 | *.debug text eol=lf merge=union
11 |
12 |
13 | /packages/core/index.js linguist-detectable=false
14 | /packages/core/index.d.ts linguist-detectable=false
15 | /packages/core/oxc-node.wasi-browser.js linguist-detectable=false
16 | /packages/core/oxc-node.wasi.cjs linguist-detectable=false
17 | /packages/core/wasi-workser.browser.mjs linguist-detectable=false
18 | /packages/core/wasi-worker.mjs linguist-detectable=false
19 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/js-module.js:
--------------------------------------------------------------------------------
1 | /* eslint import/order: off */
2 | import assert from "node:assert";
3 | import test from "node:test";
4 |
5 | import { supportedExtensions } from "file-type";
6 |
7 | import { bar as subBar } from "@subdirectory/bar.ts";
8 | import { foo } from "./foo.ts";
9 | import { bar } from "./subdirectory/bar.ts";
10 | import { baz } from "./subdirectory/index.ts";
11 |
12 | await test("js:file-type should work", () => {
13 | assert.ok(supportedExtensions.has("jpg"));
14 | });
15 |
16 | await test("js:resolve adjacent file path", () => {
17 | assert.equal(foo(), "foo");
18 | });
19 |
20 | await test("js:resolve nested file path", () => {
21 | assert.equal(bar(), "bar");
22 | });
23 |
24 | await test("js:resolve nested entry point", () => {
25 | assert.equal(baz(), "baz");
26 | });
27 |
28 | await test("js:resolve paths", () => {
29 | assert.equal(subBar(), "bar");
30 | });
31 |
--------------------------------------------------------------------------------
/packages/integrate-module/src/js-module.mjs:
--------------------------------------------------------------------------------
1 | /* eslint import/order: off */
2 | import assert from "node:assert";
3 | import test from "node:test";
4 |
5 | import { supportedExtensions } from "file-type";
6 |
7 | import { bar as subBar } from "@subdirectory/bar.mts";
8 | import { foo } from "./foo.mts";
9 | import { bar } from "./subdirectory/bar.mts";
10 | import { baz } from "./subdirectory/index.mts";
11 |
12 | await test("js:file-type should work", () => {
13 | assert.ok(supportedExtensions.has("jpg"));
14 | });
15 |
16 | await test("js:resolve adjacent file path", () => {
17 | assert.equal(foo(), "foo");
18 | });
19 |
20 | await test("js:resolve nested file path", () => {
21 | assert.equal(bar(), "bar");
22 | });
23 |
24 | await test("js:resolve nested entry point", () => {
25 | assert.equal(baz(), "baz");
26 | });
27 |
28 | await test("js:resolve paths", () => {
29 | assert.equal(subBar(), "bar");
30 | });
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # `oxc-node`
2 |
3 | [![Build Status][ci-badge]][ci-url]
4 | [![npmjs.com][npm-badge]][npm-url]
5 |
6 | Fast and friendly Node.js dev tool based on [Oxc](https://github.com/oxc-project/oxc).
7 |
8 | ## `@oxc-node/core`
9 |
10 | Transformer and register for Node.js projects.
11 |
12 | ### Usage
13 |
14 | ```bash
15 | node --import @oxc-node/core/register ./path/to/entry.ts
16 | ```
17 |
18 | ## [Sponsored By](https://github.com/sponsors/Boshen)
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | [ci-badge]: https://github.com/oxc-project/oxc-node/actions/workflows/CI.yml/badge.svg?branch=main
27 | [ci-url]: https://github.com/oxc-project/oxc-node/actions/workflows/CI.yml
28 | [npm-url]: https://www.npmjs.com/package/@oxc-node/core
29 | [npm-badge]: https://img.shields.io/npm/dw/@oxc-node/core?label=npm
30 |
--------------------------------------------------------------------------------
/packages/core/wasi-worker-browser.mjs:
--------------------------------------------------------------------------------
1 | import { instantiateNapiModuleSync, MessageHandler, WASI } from "@napi-rs/wasm-runtime";
2 |
3 | const handler = new MessageHandler({
4 | onLoad({ wasmModule, wasmMemory }) {
5 | const wasi = new WASI({
6 | print: function () {
7 | // eslint-disable-next-line no-console
8 | console.log.apply(console, arguments);
9 | },
10 | printErr: function () {
11 | // eslint-disable-next-line no-console
12 | console.error.apply(console, arguments);
13 | },
14 | });
15 | return instantiateNapiModuleSync(wasmModule, {
16 | childThread: true,
17 | wasi,
18 | overwriteImports(importObject) {
19 | importObject.env = {
20 | ...importObject.env,
21 | ...importObject.napi,
22 | ...importObject.emnapi,
23 | memory: wasmMemory,
24 | };
25 | },
26 | });
27 | },
28 | });
29 |
30 | globalThis.onmessage = function (e) {
31 | handler.handle(e);
32 | };
33 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "integrate-module-bundler",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "test": "oxnode -C dev ./src/index.ts"
8 | },
9 | "dependencies": {
10 | "file-type": "^21.0.0",
11 | "p-timeout": "^7.0.0"
12 | },
13 | "devDependencies": {
14 | "@napi-rs/tar": "^1.0.0",
15 | "@napi-rs/wasm-runtime": "^1.0.1",
16 | "@nestjs/common": "^11.1.5",
17 | "@nestjs/core": "^11.1.5",
18 | "@nestjs/platform-express": "^11.1.5",
19 | "@oxc-node/cli": "workspace:*",
20 | "@oxc-project/runtime": "^0.103.0",
21 | "@types/express": "^5.0.3",
22 | "@types/node": "^25.0.0",
23 | "@types/react": "^19.1.8",
24 | "@types/react-dom": "^19.1.6",
25 | "condition-dev": "workspace:*",
26 | "core-js": "^3.44.0",
27 | "express": "^5.1.0",
28 | "react": "^19.1.0",
29 | "react-dom": "^19.1.0",
30 | "simple-git": "^3.28.0",
31 | "ts-node": "^10.9.2",
32 | "tsx": "^4.20.3"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/integrate-module-bundler/src/babel-generated-double-default/index.js:
--------------------------------------------------------------------------------
1 | // this undesirable output was commonly generated by babel w browser-breaking
2 | // defineProperty and default.default definitions
3 |
4 | /* eslint-disable */
5 | "use strict";
6 |
7 | Object.defineProperty(exports, "__esModule", {
8 | value: true,
9 | });
10 | exports["default"] = void 0;
11 |
12 | function _typeof(obj) {
13 | "@babel/helpers - typeof";
14 | if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
15 | _typeof = function _typeof(obj) {
16 | return typeof obj;
17 | };
18 | } else {
19 | _typeof = function _typeof(obj) {
20 | return obj &&
21 | typeof Symbol === "function" &&
22 | obj.constructor === Symbol &&
23 | obj !== Symbol.prototype
24 | ? "symbol"
25 | : typeof obj;
26 | };
27 | }
28 | return _typeof(obj);
29 | }
30 |
31 | var _default = function _default() {
32 | return "default.default";
33 | };
34 |
35 | exports["default"] = _default;
36 | /* eslint-enable */
37 |
--------------------------------------------------------------------------------
/.github/workflows/zizmor.yml:
--------------------------------------------------------------------------------
1 | name: GitHub Actions Security Analysis
2 |
3 | on:
4 | workflow_dispatch:
5 | pull_request:
6 | types: [opened, synchronize]
7 | paths:
8 | - ".github/workflows/**"
9 | push:
10 | branches:
11 | - main
12 | paths:
13 | - ".github/workflows/**"
14 |
15 | permissions: {}
16 |
17 | jobs:
18 | zizmor:
19 | name: zizmor
20 | runs-on: ubuntu-latest
21 | permissions:
22 | security-events: write
23 | steps:
24 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
25 | with:
26 | persist-credentials: false
27 |
28 | - uses: taiki-e/install-action@5818d9684d2a52207bb7475983a18ba56127e337 # v2.63.2
29 | with:
30 | tool: zizmor
31 |
32 | - run: zizmor --format sarif . > results.sarif
33 | env:
34 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 |
36 | - uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
37 | with:
38 | sarif_file: results.sarif
39 | category: zizmor
40 |
--------------------------------------------------------------------------------
/.github/workflows/autofix.yml:
--------------------------------------------------------------------------------
1 | name: autofix.ci # For security reasons, the workflow in which the autofix.ci action is used must be named "autofix.ci".
2 |
3 | permissions: {}
4 |
5 | on:
6 | pull_request:
7 | types: [opened, synchronize]
8 |
9 | concurrency:
10 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
11 | cancel-in-progress: ${{ github.ref_name != 'main' }}
12 |
13 | jobs:
14 | autofix:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: taiki-e/checkout-action@b13d20b7cda4e2f325ef19895128f7ff735c0b3d # v1.3.1
18 |
19 | - uses: oxc-project/setup-rust@ecabb7322a2ba5aeedb3612d2a40b86a85cee235 # v1.0.11
20 | with:
21 | restore-cache: false
22 | tools: cargo-shear@1
23 | components: rustfmt
24 |
25 | - uses: oxc-project/setup-node@141eb77546de6702f92d320926403fe3f9f6a6f2 # v1.0.5
26 |
27 | - run: cargo shear --fix
28 | - run: node --run fmt
29 |
30 | - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # v1.3.2
31 | with:
32 | fail-fast: false
33 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oxc-node",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "bench": "pnpm --filter=bench bench",
7 | "fmt": "oxfmt && cargo fmt",
8 | "lint": "oxlint",
9 | "test": "pnpm --sequential --filter=integrate* run test",
10 | "prepare": "husky"
11 | },
12 | "lint-staged": {
13 | "*": [
14 | "oxfmt --no-error-on-unmatched-pattern"
15 | ],
16 | "*.@(js|ts|tsx)": [
17 | "oxlint --fix"
18 | ]
19 | },
20 | "devDependencies": {
21 | "@napi-rs/cli": "catalog:",
22 | "@napi-rs/wasm-runtime": "^1.0.1",
23 | "@oxc-node/cli": "workspace:*",
24 | "@oxc-node/core": "workspace:*",
25 | "@oxc-project/runtime": "^0.103.0",
26 | "@types/node": "^25.0.0",
27 | "ava": "^6.4.1",
28 | "cross-env": "^10.0.0",
29 | "emnapi": "^1.4.5",
30 | "husky": "^9.1.7",
31 | "lerna": "^9.0.0",
32 | "lint-staged": "^16.1.2",
33 | "npm-run-all2": "^8.0.4",
34 | "oxfmt": "^0.18.0",
35 | "oxlint": "^1.8.0",
36 | "typescript": "^5.8.3"
37 | },
38 | "packageManager": "pnpm@10.25.0"
39 | }
40 |
--------------------------------------------------------------------------------
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [target.'cfg(target_env = "gnu")']
2 | rustflags = ["-C", "link-args=-Wl,-z,nodelete"]
3 |
4 | [target.x86_64-pc-windows-msvc]
5 | rustflags = ["-C", "target-feature=+crt-static"]
6 |
7 | [target.i686-pc-windows-msvc]
8 | rustflags = ["-C", "target-feature=+crt-static"]
9 |
10 | [target.aarch64-pc-windows-msvc]
11 | rustflags = ["-C", "target-feature=+crt-static"]
12 |
13 | [target.'cfg(target_os = "windows")']
14 | rustflags = [
15 | # Disables linking against the default Universal C Runtime (libucrt.lib). This prevents conflicts if another CRT library is linked manually.
16 | "-C",
17 | "link-args=/NODEFAULTLIB:libucrt.lib",
18 | # Manually adds ucrt.lib (the Universal CRT) as a default library to link against, replacing the one you just excluded above.
19 | # This ensures consistent linking when multiple CRTs might be available.
20 | "-C",
21 | "link-args=/DEFAULTLIB:ucrt.lib",
22 | ]
23 |
24 | # LLD linker is currently broken for us, opt out.
25 | # https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/#what-s-in-1-90-0-stable
26 | [target.x86_64-unknown-linux-gnu]
27 | rustflags = ["-C", "linker-features=-lld"]
28 |
--------------------------------------------------------------------------------
/packages/cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@oxc-node/cli",
3 | "version": "0.0.35",
4 | "description": "OXC Node cli",
5 | "homepage": "https://github.com/oxc-project/oxc-node/tree/main/packages/cli",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/oxc-project/oxc-node.git"
9 | },
10 | "funding": [
11 | {
12 | "type": "github",
13 | "url": "https://github.com/sponsors/Brooooooklyn"
14 | },
15 | {
16 | "type": "github",
17 | "url": "https://github.com/sponsors/Boshen"
18 | }
19 | ],
20 | "license": "MIT",
21 | "type": "module",
22 | "bin": {
23 | "oxnode": "./dist/index.js"
24 | },
25 | "files": [
26 | "dist"
27 | ],
28 | "scripts": {
29 | "build": "rolldown --config ./rolldown.config.js",
30 | "dev": "node --import @oxc-node/core/register ./src/index.ts"
31 | },
32 | "dependencies": {
33 | "@oxc-node/core": "workspace:*"
34 | },
35 | "devDependencies": {
36 | "clipanion": "^4.0.0-rc.4",
37 | "rolldown": "^1.0.0-beta.29"
38 | },
39 | "publishConfig": {
40 | "access": "public",
41 | "registry": "https://registry.npmjs.org/"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "oxc-node"
3 | version = "0.0.0"
4 | authors = ["LongYinan "]
5 | edition = "2024"
6 |
7 | [lib]
8 | crate-type = ["cdylib"]
9 |
10 | [dependencies]
11 | napi = { version = "3.5.1", default-features = false, features = ["serde-json", "napi3"] }
12 | napi-derive = { version = "3.3.2", default-features = false, features = ["type-def"] }
13 | oxc = { version = "0.103.0", features = ["codegen", "transformer", "semantic", "regular_expression"] }
14 | oxc_resolver = { version = "11.13.1" }
15 | phf = "0.13"
16 | serde_json = "1"
17 | tracing = "0.1"
18 | tracing-subscriber = { version = "0.3", default-features = false, features = ["std", "fmt"] } # Omit the `regex` feature
19 |
20 | [target.'cfg(all(not(target_os = "linux"), not(target_os = "freebsd"), not(target_arch = "arm"), not(target_arch = "x86"), not(target_family = "wasm")))'.dependencies]
21 | mimalloc-safe = { version = "0.1", features = ["skip_collect_on_exit"] }
22 |
23 | [target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies]
24 | mimalloc-safe = { version = "0.1", features = ["skip_collect_on_exit", "local_dynamic_tls"] }
25 |
26 | [build-dependencies]
27 | napi-build = "2"
28 |
29 | [profile.release]
30 | codegen-units = 1
31 | lto = true
32 | strip = "symbols"
33 |
--------------------------------------------------------------------------------
/packages/core/register.mjs:
--------------------------------------------------------------------------------
1 | import * as NodeModule from "node:module";
2 |
3 | import { addHook } from "pirates";
4 |
5 | import { OxcTransformer } from "./index.js";
6 |
7 | // Destructure from NodeModule namespace to support older Node.js versions
8 | const { register, setSourceMapsSupport } = NodeModule;
9 |
10 | const DEFAULT_EXTENSIONS = new Set([
11 | ".js",
12 | ".jsx",
13 | ".ts",
14 | ".tsx",
15 | ".mjs",
16 | ".mts",
17 | ".cjs",
18 | ".cts",
19 | ".es6",
20 | ".es",
21 | ]);
22 |
23 | register("@oxc-node/core/esm", import.meta.url);
24 |
25 | if (typeof setSourceMapsSupport === "function") {
26 | setSourceMapsSupport(true, { nodeModules: true, generatedCode: true });
27 | } else if (typeof process.setSourceMapsEnabled === "function") {
28 | process.setSourceMapsEnabled(true);
29 | }
30 |
31 | const transformer = new OxcTransformer(process.cwd());
32 | const SOURCEMAP_PREFIX = "\n//# sourceMappingURL=";
33 | const SOURCEMAP_MIME = "data:application/json;charset=utf-8;base64,";
34 |
35 | addHook(
36 | (code, filename) => {
37 | const output = transformer.transform(filename, code);
38 | let transformed = output.source();
39 | const sourceMap = output.sourceMap();
40 |
41 | if (sourceMap) {
42 | const inlineMap = Buffer.from(sourceMap, "utf8").toString("base64");
43 | transformed += SOURCEMAP_PREFIX + SOURCEMAP_MIME + inlineMap;
44 | }
45 |
46 | return transformed;
47 | },
48 | {
49 | ext: Array.from(DEFAULT_EXTENSIONS),
50 | },
51 | );
52 |
--------------------------------------------------------------------------------
/packages/core/reexport-oxc-runtime.mjs:
--------------------------------------------------------------------------------
1 | import { copyFile, mkdir, readdir, writeFile } from "node:fs/promises";
2 | import { createRequire } from "node:module";
3 | import { join } from "node:path";
4 |
5 | import oxcRuntimePackageJson from "@oxc-project/runtime/package.json" with { type: "json" };
6 |
7 | import currentPackageJson from "./package.json" with { type: "json" };
8 |
9 | const { resolve } = createRequire(import.meta.url);
10 |
11 | const currentDir = join(resolve("."), "..");
12 |
13 | const oxcRuntimeDir = join(resolve("@oxc-project/runtime/package.json"), "..");
14 |
15 | const files = await readdir(oxcRuntimeDir, { recursive: true });
16 |
17 | await mkdir(join(currentDir, "src", "helpers", "esm"), { recursive: true }).catch(() => {
18 | // ignore error
19 | });
20 |
21 | for (const file of files.filter((file) => file.endsWith(".js"))) {
22 | const filePath = join(oxcRuntimeDir, file);
23 | await copyFile(filePath, join(currentDir, file));
24 | }
25 |
26 | const packageJsonExports = {
27 | ".": {
28 | import: "./index.js",
29 | require: "./index.js",
30 | types: "./index.d.ts",
31 | },
32 | "./esm": {
33 | import: "./esm.mjs",
34 | },
35 | "./esm.mjs": {
36 | import: "./esm.mjs",
37 | },
38 | "./register": {
39 | import: "./register.mjs",
40 | },
41 | "./register.mjs": {
42 | import: "./register.mjs",
43 | },
44 | ...oxcRuntimePackageJson.exports,
45 | };
46 |
47 | await writeFile(
48 | join(currentDir, "package.json"),
49 | JSON.stringify(
50 | {
51 | ...currentPackageJson,
52 | exports: packageJsonExports,
53 | },
54 | null,
55 | 2,
56 | ),
57 | );
58 |
--------------------------------------------------------------------------------
/packages/bench/index.ts:
--------------------------------------------------------------------------------
1 | import { readFile } from "node:fs/promises";
2 | import { join } from "node:path";
3 | import { fileURLToPath } from "node:url";
4 |
5 | import { transform as oxc } from "@oxc-node/core";
6 | import { transformSync as swc } from "@swc/core";
7 | import { transformSync as esbuild } from "esbuild";
8 | import { Bench } from "tinybench";
9 | import ts from "typescript";
10 |
11 | // https://github.com/tinylibs/tinybench/issues/83
12 | const bench = new Bench({ iterations: 1000 });
13 |
14 | const fixture = (
15 | await readFile(
16 | join(fileURLToPath(import.meta.url), "..", "node_modules/rxjs/src/internal/ajax/ajax.ts"),
17 | )
18 | ).toString("utf8");
19 |
20 | bench
21 | .add("@swc/core", () => {
22 | swc(fixture, {
23 | filename: "ajax.ts",
24 | jsc: {
25 | target: "esnext",
26 | parser: {
27 | syntax: "typescript",
28 | tsx: false,
29 | dynamicImport: false,
30 | decorators: false,
31 | },
32 | },
33 | sourceMaps: true,
34 | });
35 | })
36 | .add("oxc", () => {
37 | const { source: _source, sourceMap: _sourceMap } = oxc("ajax.ts", fixture);
38 | })
39 | .add("esbuild", () => {
40 | esbuild(fixture, {
41 | loader: "ts",
42 | format: "esm",
43 | target: "esnext",
44 | });
45 | })
46 | .add("typescript", () => {
47 | ts.transpileModule(fixture, {
48 | fileName: "ajax.ts",
49 | compilerOptions: {
50 | target: ts.ScriptTarget.ESNext,
51 | module: ts.ModuleKind.ESNext,
52 | isolatedModules: true,
53 | sourceMap: true,
54 | },
55 | });
56 | });
57 |
58 | await bench.run();
59 |
60 | console.table(bench.table());
61 |
--------------------------------------------------------------------------------
/packages/core/wasi-worker.mjs:
--------------------------------------------------------------------------------
1 | import fs from "node:fs";
2 | import { createRequire } from "node:module";
3 | import { parse } from "node:path";
4 | import { WASI } from "node:wasi";
5 | import { parentPort, Worker } from "node:worker_threads";
6 |
7 | const require = createRequire(import.meta.url);
8 |
9 | const {
10 | instantiateNapiModuleSync,
11 | MessageHandler,
12 | getDefaultContext,
13 | } = require("@napi-rs/wasm-runtime");
14 |
15 | if (parentPort) {
16 | parentPort.on("message", (data) => {
17 | globalThis.onmessage({ data });
18 | });
19 | }
20 |
21 | Object.assign(globalThis, {
22 | self: globalThis,
23 | require,
24 | Worker,
25 | importScripts: function (f) {
26 | (0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
27 | },
28 | postMessage: function (msg) {
29 | if (parentPort) {
30 | parentPort.postMessage(msg);
31 | }
32 | },
33 | });
34 |
35 | const emnapiContext = getDefaultContext();
36 |
37 | const __rootDir = parse(process.cwd()).root;
38 |
39 | const handler = new MessageHandler({
40 | onLoad({ wasmModule, wasmMemory }) {
41 | const wasi = new WASI({
42 | version: "preview1",
43 | env: process.env,
44 | preopens: {
45 | [__rootDir]: __rootDir,
46 | },
47 | });
48 |
49 | return instantiateNapiModuleSync(wasmModule, {
50 | childThread: true,
51 | wasi,
52 | context: emnapiContext,
53 | overwriteImports(importObject) {
54 | importObject.env = {
55 | ...importObject.env,
56 | ...importObject.napi,
57 | ...importObject.emnapi,
58 | memory: wasmMemory,
59 | };
60 | },
61 | });
62 | },
63 | });
64 |
65 | globalThis.onmessage = function (e) {
66 | handler.handle(e);
67 | };
68 |
--------------------------------------------------------------------------------
/packages/core/oxc-node.wasi-browser.js:
--------------------------------------------------------------------------------
1 | import {
2 | createOnMessage as __wasmCreateOnMessageForFsProxy,
3 | getDefaultContext as __emnapiGetDefaultContext,
4 | instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
5 | WASI as __WASI,
6 | } from "@napi-rs/wasm-runtime";
7 |
8 | const __wasi = new __WASI({
9 | version: "preview1",
10 | });
11 |
12 | const __wasmUrl = new URL("./oxc-node.wasm32-wasi.wasm", import.meta.url).href;
13 | const __emnapiContext = __emnapiGetDefaultContext();
14 |
15 | const __sharedMemory = new WebAssembly.Memory({
16 | initial: 16384,
17 | maximum: 65536,
18 | shared: true,
19 | });
20 |
21 | const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer());
22 |
23 | const {
24 | instance: __napiInstance,
25 | module: __wasiModule,
26 | napiModule: __napiModule,
27 | } = __emnapiInstantiateNapiModuleSync(__wasmFile, {
28 | context: __emnapiContext,
29 | asyncWorkPoolSize: 4,
30 | wasi: __wasi,
31 | onCreateWorker() {
32 | const worker = new Worker(new URL("./wasi-worker-browser.mjs", import.meta.url), {
33 | type: "module",
34 | });
35 |
36 | return worker;
37 | },
38 | overwriteImports(importObject) {
39 | importObject.env = {
40 | ...importObject.env,
41 | ...importObject.napi,
42 | ...importObject.emnapi,
43 | memory: __sharedMemory,
44 | };
45 | return importObject;
46 | },
47 | beforeInit({ instance }) {
48 | for (const name of Object.keys(instance.exports)) {
49 | if (name.startsWith("__napi_register__")) {
50 | instance.exports[name]();
51 | }
52 | }
53 | },
54 | });
55 | export default __napiModule.exports;
56 | export const Output = __napiModule.exports.Output;
57 | export const OxcTransformer = __napiModule.exports.OxcTransformer;
58 | export const createResolve = __napiModule.exports.createResolve;
59 | export const initTracing = __napiModule.exports.initTracing;
60 | export const load = __napiModule.exports.load;
61 | export const transform = __napiModule.exports.transform;
62 | export const transformAsync = __napiModule.exports.transformAsync;
63 |
--------------------------------------------------------------------------------
/packages/integrate-ava/__tests__/cli.spec.ts:
--------------------------------------------------------------------------------
1 | import test, { ExecutionContext } from "ava";
2 | import { spawnSync } from "node:child_process";
3 | import { fileURLToPath, pathToFileURL } from "node:url";
4 |
5 | const STACKTRACE_LINE = 6;
6 | const STACKTRACE_COLUMN = 12;
7 | const FIXTURE_PATHS = new Map(
8 | ["stacktrace-esm.ts", "stacktrace-esm.mts", "stacktrace-cjs.cts"].map((name) => [
9 | name,
10 | fileURLToPath(new URL(`./fixtures/${name}`, import.meta.url)),
11 | ]),
12 | );
13 | const getFixturePath = (fixtureName: string) => {
14 | const resolved = FIXTURE_PATHS.get(fixtureName);
15 | if (!resolved) {
16 | throw new Error(`Unknown fixture: ${fixtureName}`);
17 | }
18 | return resolved;
19 | };
20 | const runCliFixture = (fixtureName: string) => {
21 | const fixturePath = getFixturePath(fixtureName);
22 | const result = spawnSync(
23 | process.execPath,
24 | ["--import", "@oxc-node/core/register", "--test", fixturePath],
25 | {
26 | encoding: "utf8",
27 | env: {
28 | ...process.env,
29 | NODE_OPTIONS: undefined,
30 | },
31 | },
32 | );
33 |
34 | return { ...result, fixturePath };
35 | };
36 | const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
37 | const expectStackLocation = (t: ExecutionContext, output: string, fixturePath: string) => {
38 | const fileUrl = pathToFileURL(fixturePath).href;
39 | const pattern = new RegExp(
40 | `(?:${escapeRegExp(fileUrl)}|${escapeRegExp(fixturePath)}):(\\d+):(\\d+)`,
41 | "g",
42 | );
43 | const matches = [...output.matchAll(pattern)];
44 |
45 | t.true(matches.length > 0, "stack trace should reference the failing fixture path");
46 |
47 | const exactLocation = matches.find(([, line, column]) => {
48 | return Number(line) === STACKTRACE_LINE && Number(column) === STACKTRACE_COLUMN;
49 | });
50 |
51 | t.truthy(exactLocation, "stack trace should include the original TypeScript location");
52 | };
53 |
54 | for (const fixture of FIXTURE_PATHS.keys()) {
55 | test(`CLI stack trace for ${fixture}`, (t) => {
56 | const { stdout, stderr, status, error, fixturePath } = runCliFixture(fixture);
57 |
58 | t.falsy(error, error?.message);
59 | t.not(status, 0, "fixture should fail to trigger stack trace output");
60 |
61 | expectStackLocation(t, `${stdout}${stderr}`, fixturePath);
62 | });
63 | }
64 |
--------------------------------------------------------------------------------
/packages/cli/src/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import { exec, execSync } from "node:child_process";
4 | import process from "node:process";
5 |
6 | import { Builtins, Cli, Command, Option, Usage } from "clipanion";
7 |
8 | import pkgJson from "../package.json" with { type: "json" };
9 |
10 | const [node, app, ...stdArgs] = process.argv;
11 |
12 | class MainCommand extends Command {
13 | static paths = [[]];
14 |
15 | static usage: Usage = {
16 | description: `Run a script with oxc transformer and oxc-resolver`,
17 | details: `oxnode is a CLI tool that runs a script with oxc transformer and oxc-resolver.
18 | The esm module is resolved by oxc-resolver and transformed by oxc transformer.
19 | The cjs module support will be added in the future.
20 | `,
21 | examples: [
22 | [`Run a script`, `oxnode ./src/index.ts`],
23 | [`repl`, `oxnode`],
24 | ],
25 | };
26 |
27 | help = Option.Boolean(`-h,--help`, false, {
28 | description: `Show help`,
29 | });
30 |
31 | nodeHelp = Option.Boolean(`--node-help`, false, {
32 | description: `Show Node.js help`,
33 | });
34 |
35 | args = Option.Proxy();
36 |
37 | async execute() {
38 | if (this.help) {
39 | this.context.stdout.write(this.cli.usage());
40 | return;
41 | }
42 | if (this.nodeHelp) {
43 | this.args.push(`--help `);
44 | }
45 | const args = this.args.length ? `${this.args.join(" ")}` : "";
46 | const register = import.meta.resolve("@oxc-node/core/register");
47 | if (!args.length) {
48 | execSync(`node --enable-source-maps --import ${register}`, {
49 | env: process.env,
50 | cwd: process.cwd(),
51 | stdio: `inherit`,
52 | });
53 | return;
54 | }
55 | const cp = exec(`node --enable-source-maps --import ${register} ${args}`, {
56 | env: process.env,
57 | cwd: process.cwd(),
58 | });
59 | cp.addListener(`error`, (error) => {
60 | console.error(error);
61 | });
62 | if (cp.stdin) {
63 | this.context.stdin.pipe(cp.stdin);
64 | }
65 | if (cp.stdout) {
66 | cp.stdout.pipe(this.context.stdout);
67 | }
68 | if (cp.stderr) {
69 | cp.stderr.pipe(this.context.stderr);
70 | }
71 | cp.addListener(`exit`, (code) => {
72 | process.exit(code ?? 0);
73 | });
74 | }
75 | }
76 |
77 | const cli = new Cli({
78 | binaryLabel: `oxnode`,
79 | binaryName: `${node} ${app}`,
80 | binaryVersion: pkgJson.version,
81 | });
82 |
83 | cli.register(MainCommand);
84 | cli.register(Builtins.HelpCommand);
85 | cli.register(Builtins.VersionCommand);
86 | cli.runExit(stdArgs);
87 |
--------------------------------------------------------------------------------
/packages/core/index.d.ts:
--------------------------------------------------------------------------------
1 | /* auto-generated by NAPI-RS */
2 | /* eslint-disable */
3 | export declare class Output {
4 | /**
5 | * Returns the generated code
6 | * Cache the result of this function if you need to use it multiple times
7 | */
8 | source(): string;
9 | /**
10 | * Returns the source map as a JSON string
11 | * Cache the result of this function if you need to use it multiple times
12 | */
13 | sourceMap(): string | null;
14 | }
15 |
16 | export declare class OxcTransformer {
17 | constructor(cwd?: string | undefined | null);
18 | transform(path: string, source: string | Uint8Array): Output;
19 | transformAsync(path: string, source: string | Uint8Array | Buffer): Promise