Documentation content

Introduction

scriptc is a compiler that turns TypeScript and JavaScript into native executables and WebAssembly modules. It uses the types checked by the TypeScript compiler to generate machine code, and the output runs without Node.js installed.

scriptc is experimental. It supports a subset of JavaScript, TypeScript, and the Node.js APIs, and it tells you at build time when a program uses something outside that subset.

Features

  • Native output. scriptc build produces an executable for macOS, Linux, or Windows, or a WebAssembly module.
  • Standard TypeScript. Programs are type-checked by the TypeScript compiler using your tsconfig.json. No annotations or language extensions are required.
  • npm dependencies. Packages your program imports compile to native code together with your own code.
  • Coverage reports. scriptc coverage shows what compiles and explains anything that doesn't, with a diagnostic code, a source location, and usually a rewrite hint.

What you can build

Compile a program

Create a TypeScript file:

fib.ts
function fib(n: number): number {
  return n < 2 ? n : fib(n - 1) + fib(n - 2);
}
console.log(fib(30));

scriptc run compiles the file and runs the result:

$ scriptc run fib.ts
832040

scriptc build writes an executable:

$ scriptc build fib.ts -o fib >/dev/null
$ ./fib
832040

The Quickstart covers installation and a first build.

How it works

scriptc type-checks your program with TypeScript, uses the checked types to choose a native representation for every value, and generates machine code with LLVM. The executable links a native runtime that provides memory management, the event loop, and the Node.js APIs your program uses. How It Works describes each stage.

Language and API support

scriptc compiles supported forms of:

  • Classes, inheritance, closures, generics, discriminated unions, destructuring, and spread.
  • async/await, promises, exceptions, iterators, and resource disposal.
  • Strings, BigInts, arrays, Maps, Sets, JSON, Math, typed arrays, and Buffers.
  • Node.js filesystem, path, process, child-process, crypto, timer, and networking APIs.

Programs are checked against the es2025 standard library, scriptc's own declarations, and your project's declarations such as @types/node. The Node.js compatibility reference lists API-level support, and Limitations describes the remaining restrictions and the places where compiled programs behave differently from Node.js.

Runtime type checks

Compiled code relies on types, so scriptc checks a value whose type is only known at runtime before using it as a specific type. For example, parsed JSON must match the type you cast it to:

cast.ts
type Config = { port: number };

try {
  const config = JSON.parse('{"port": "eighty"}') as Config;
  console.log(config.port);
} catch (error) {
  if (error instanceof Error) console.log(error.message);
}
$ scriptc run cast.ts
expected number at $.port, got string

Under Node.js, the same as Config assertion performs no check. See runtime type checks for details.

Build-time evaluation

comptime(() => ...) runs a function while the program compiles and embeds its result as a constant:

label.ts
const label = comptime(() => "hello".toUpperCase());
console.log(label);
$ scriptc run label.ts
HELLO

Next steps