scriptc logo

scriptc

TypeScript-to-Native Compiler

Developer ToolsTypeScriptApache-2.0 2.4k 45Health 82
Website GitHub

What is it?

What it is

scriptc is a zero‑runtime TypeScript compiler that turns ordinary TypeScript code into small, fast native executables with no embedded JavaScript engine. It type‑checks with the real TypeScript compiler, lowers the code to a typed intermediate representation, and then compiles it to native machine code via LLVM or a C backend.

Why it exists

It exists to give TypeScript developers the performance and footprint of compiled languages while preserving the full language, standard library, and Node API surface. By statically compiling what can be statically determined, scriptc eliminates the Node/V8 runtime, reduces startup time, binary size, and memory usage, and provides deterministic, byte‑for‑byte behavior identical to Node.

Who should use it

TypeScript developers needing native binaries, performance-critical applications, or systems requiring minimal runtime dependencies

Who should avoid it

Projects relying on Node.js-specific features not supported by scriptc, or users unfamiliar with TypeScript's static analysis

How it works

A quick walkthrough in plain English

How scriptc works

Step 1 of 3

You interact with it

Open scriptc, send a request, or connect it to your stack.

Features

Zero-runtime TypeScript compilation to native executables
Static compilation of TypeScript constructs to native code (default)
Dynamic mode (--dynamic) embeds QuickJS engine for unsupported features
Coverage analysis showing static vs dynamic statements
Native FFI for calling C ABI directly
Comptime execution of TypeScript at build time
Full Node.js API surface support (fs, net, http, crypto, etc.)
WHATWG fetch and web streams support
npm dependencies can be bundled via --dynamic
Differential testing against Node for byte-for-byte correctness
Memory safety via AddressSanitizer and reference-count audit
C backend with LLVM fallback, readable source-line-annotated output

Advantages

  • Very small binary size (~170-200KB static, ~3MB with dynamic deps)
  • Fast startup (~2.4ms vs Node ~47ms)
  • Low memory footprint (1-4MB RSS vs Node 67-116MB)
  • No Node, V8, or JavaScript engine required in static binaries
  • TypeScript type-checked by real tsc, guaranteeing correctness
  • Static code compiles to native with JS-exact semantics
  • Explicit error codes and hints for unsupported constructs
  • Ability to opt-in dynamic features only when needed
  • Built-in validation for type casts (JSON.parse as Config)
  • Transparent fallback to C backend for portability
  • Sanitized testing ensures memory safety and leak detection

Disadvantages

  • Primary platform is macOS arm64; Linux/Windows rely on cross-compilation
  • Requires clang (Xcode Command Line Tools) to build
  • Some TypeScript features (optional parameters as values, Promise.reject) are not static and need --dynamic or rewrites
  • npm dependencies and any-typed code require --dynamic mode, increasing binary size
  • Certain Node internals (timing, error-object properties) have deliberate divergences from Node
  • Static compilation may reject code that works in Node, requiring adjustments
  • Limited to features that can be lowered; unsupported constructs cause build errors
  • Development workflow may need sandboxed testing for cross-platform validation

Installation

native

npm install -g scriptc

FAQ

What is scriptc and how does it differ from running TypeScript with Node?

scriptc compiles ordinary TypeScript into a small, fast native executable that contains no JavaScript engine. Unlike Node, which interprets JavaScript at runtime, scriptc produces a binary that runs natively, offering ~2 ms startup, 1–4 MB memory usage, and a binary size of 170–200 KB for static builds. The compiled code is byte‑for‑byte identical to Node’s output, but without the overhead of a V8 or JavaScript engine.

How do I install scriptc?

Run `npm install -g scriptc`. The tool requires clang (preinstalled with Xcode Command Line Tools). macOS arm64 is the primary platform; Linux and Windows binaries are built by cross‑compilation and verified by differential tests.

Which parts of my TypeScript code compile statically and when do I need to use `--dynamic`?

scriptc statically compiles the language core, the standard library, Node’s API surface, and the WHATWG web subset. Code that uses optional parameters as values, `any` types, or npm dependencies that ship JavaScript will be blocked unless you opt in with `--dynamic`. In that mode, an embedded QuickJS engine executes the dynamic parts, and values crossing into static code are runtime‑validated.

How does scriptc guarantee that the native binary behaves the same as Node?

Two enforcement mechanisms run on every change: differential testing, which runs a corpus of 800+ programs under both Node and scriptc and compares stdout, stderr, and exit codes byte‑for‑byte; and a memory‑safety lane that re‑runs the corpus under AddressSanitizer with a reference‑count audit to catch leaks and use‑after‑free. Any divergence is reported as a diagnostic.

How can I use native FFI with scriptc?

Use the `--ffi` flag to bind TypeScript declarations that specify only the signature to direct C ABI calls. Provide the required archives, objects, or system libraries via a manifest. The boundary is explicit and length‑delimited, and the Native FFI guide explains the process in detail.

What is the sandbox testing workflow for scriptc?

Run `pnpm test` for differential and sanitizer tests locally. For sandboxed tests, set `SCRIPTC_SANDBOX_IMAGE` to a Vercel Container Registry image, then run `pnpm test:sandbox` (or `pnpm test:sandbox:image` to build the image). The sandbox uploads the dirty worktree, shards the corpus across multiple V8‑compatible sandboxes, and ensures consistent behavior across platforms.

Loading documentation…
View on GitHub

Featured in Videos

YouTube tutorials and walkthroughs for scriptc

Alternatives

Similar projects ranked by category, topics, and text overlap.

Compare
scriptc | MushyBook