Skip to content

Repository files navigation

ScriptGo

CI Go Version TypeScript Parity License: MIT Platforms

A high-performance Ahead-Of-Time (AOT) compiler compiling TypeScript to native standalone executables and WebAssembly (WASI) modules with Node.js parity.


ScriptGo is a high-performance native compiler that runs TypeScript and JavaScript with Node.js-compatible semantics while compiling eligible code directly to standalone native binaries or WebAssembly modules. It combines the official TypeScript (Go implementation) compiler frontend for parsing, type-checking, and diagnostics with an independent Typed IR system and an LLVM IR / Native Machine Code backend.


Highlights & Features

  • High-Performance AOT Compilation: Compiles TypeScript directly to native machine code (Mach-O, ELF, PE) and WebAssembly (.wasm) via LLVM.
  • Node.js Semantic Parity: Full parity across the 386-case regression test corpus checked against Node.js v22+ (386/386, 100%).
  • WebAssembly / WASI Target: First-class Ahead-Of-Time compilation to standalone .wasm executables with --target wasm32-wasi, validated on Node.js WASI and Wasmtime.
  • Zero-Dependency Native Builds: Automatically uses system clang or auto-detects zig cc for hassle-free out-of-the-box compilation and seamless cross-compilation (macOS, Linux, Windows, WASM).
  • Fast Execution: Instantly compiles and runs scripts directly or produces optimized standalone binary builds.
  • Modern TypeScript & ECMAScript (ES2022 - ES2025):
    • Explicit Resource Management: Full using and await using resource disposal with Symbol.dispose and Symbol.asyncDispose.
    • ES2024 Set Methods: union(), intersection(), difference(), symmetricDifference(), isSubsetOf(), isSupersetOf(), isDisjointFrom().
    • ES2024 Utilities: Promise.withResolvers(), Object.groupBy(), Map.groupBy(), Array.fromAsync().
    • ES2025 Iterator Helpers: Iterator.from(), map(), filter(), take(), drop(), flatMap(), reduce(), toArray(), forEach(), some(), every(), find().
    • Types & Primitives: number (IEEE-754), bigint, string (UTF-8), boolean, symbol (with Symbol Registry), null, undefined, unknown (with type narrowing), Tuples, Enums (numeric, string, reverse mappings), Union types (T | null | undefined), Monomorphized Generics.
    • Control Flow: if/else, switch/case (with fallthrough), while, do..while, for, for..of, for..in, for await..of, Labeled statements (break label, continue label), try/catch/finally, throw, Array & Object destructuring, Spread/Rest (...), Tagged template literals, Optional chaining & calls (?., fn?.()).
    • Functions & Closures: Lexical closures, arrow functions, default/optional/rest parameters, Generators (function*, yield, yield*), Async Generators.
    • OOP & Classes: Constructors, properties, static fields/methods, Class Static Blocks (static { ... }), Getters/Setters, Inheritance (extends, super), Polymorphic VTables, instanceof.
    • Async Runtime: Promise (resolve, reject, chaining), async/await, microtask queue execution conforming to JavaScript event loop ordering.
    • Web Standards & WinterCG: Streaming fetch() & WHATWG Streams (ReadableStream, WritableStream, TransformStream), URL, URLSearchParams, TextEncoder/TextDecoder, AbortController/AbortSignal.
    • Node.js Standard Library: High-performance native implementations for core Node.js modules (node:fs, node:path, node:os, node:process, node:crypto, node:buffer, node:http, node:net, node:dgram, node:dns, node:domain, node:events, node:stream, node:assert, node:child_process, node:module, node:querystring, node:util, node:timers, node:zlib, node:tls, node:sqlite). All placeholder/dummy stubs strictly removed.

Documentation


CLI Usage

Running Code

# Compile and run immediately on host
scriptgo run examples/hello.ts

# Run with inline TypeScript code
scriptgo run -e "console.log('Hello from ScriptGo!')"

Building Standalone Executables & WebAssembly Modules

# 1. Build a native binary for the host platform
scriptgo build examples/hello.ts -o hello

# 2. Build a WebAssembly (WASI) module
scriptgo build --target wasm32-wasi examples/hello.ts -o hello.wasm

# 3. Execute the generated WASM module via Node.js WASI or Wasmtime
node -e 'const { WASI } = require("wasi"); const fs = require("fs"); const wasi = new WASI({ version: "preview1", args: ["hello.wasm"], returnOnExit: true }); const bytes = fs.readFileSync("hello.wasm"); (async () => { const mod = await WebAssembly.compile(bytes); const inst = await WebAssembly.instantiate(mod, wasi.getImportObject()); wasi.start(inst); })();'
# Or via wasmtime
wasmtime hello.wasm

# 4. Build with debug symbols
scriptgo build examples/hello.ts --debug -o hello-debug

# 5. Build with Clang sanitizers (address, undefined, leak)
scriptgo build examples/hello.ts --sanitize address,undefined -o hello-sanitized

Type Checking & Emitting IR

# Type-check and validate against the native subset
scriptgo check examples/hello.ts

# Emit LLVM IR
scriptgo emit examples/hello.ts -o hello.ll

# Emit verified Typed IR
scriptgo emit examples/hello.ts --mode typed-ir -o hello.ir

Showcase Examples

Explore the examples/ directory for complete TypeScript samples:


Toolchain & Cross-Compilation

ScriptGo uses a Clang-compatible C/LLVM compiler driver to compile emitted LLVM IR and link against the lightweight runtime:

  • System Clang: Defaults to clang in your $PATH.
  • Zig CC (zig cc): If clang is not installed or when compiling for cross targets (including --target wasm32-wasi), ScriptGo automatically utilizes zig in $PATH for zero-dependency builds and cross-compilation across platforms.

Configuring Compiler Driver & Target Triple

You can configure the C compiler driver and target triple via CLI flags or environment variables:

# 1. WebAssembly / WASI compilation
scriptgo build examples/hello.ts --target wasm32-wasi -o hello.wasm

# 2. Cross-compilation for Linux x86_64
scriptgo build examples/hello.ts --cc zigcc --target x86_64-linux-gnu -o hello-linux

# 3. Via environment variables
export SCRIPTGO_CC="zigcc"
export SCRIPTGO_TARGET="wasm32-wasi"
scriptgo build examples/hello.ts -o hello.wasm

Direct Cross-Compilation via zig cc

You can also emit LLVM IR and cross-compile with zig cc directly:

# 1. Emit LLVM IR
scriptgo emit examples/hello.ts -o module.ll

# 2. Cross-compile for Linux x86_64
zig cc -target x86_64-linux-gnu -O2 -x ir module.ll -x c internal/runtime/runtime.c -o hello-linux

# 3. Cross-compile for Windows x86_64
zig cc -target x86_64-windows-gnu -O2 -x ir module.ll -x c internal/runtime/runtime.c -o hello-windows.exe

# 4. Cross-compile for macOS ARM64
zig cc -target aarch64-macos -O2 -x ir module.ll -x c internal/runtime/runtime.c -o hello-macos

Development & Contributing

We welcome contributions! Please check out CONTRIBUTING.md to get started.

# Build binary
make build

# Run all unit & integration tests
make test

# Run TypeScript-Go frontend tests
make test-frontend

# Run Node.js parity comparison benchmark
make test-parity

Community & Security


License

This project is licensed under the MIT License.

About

High-performance native compiler that compiles TypeScript into standalone machine code binaries with Node.js semantics.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages