scriptc: Compile TypeScript to Native Executables
What scriptc is
scriptc is a compiler that turns TypeScript and JavaScript into native executables and WebAssembly modules. Rather than bundling a script together with a full JavaScript runtime, it uses TypeScript's type information to compile supported code to native instructions. A program that compiles fully statically produces a binary that runs without Node.js and without any JavaScript engine inside it.
For code that cannot be compiled statically, such as npm dependencies or any-typed code, a --dynamic flag embeds the quickjs-ng engine and includes the dependency JavaScript at build time. The result still ships as a single executable that does not read node_modules at runtime.
The project is published by Vercel Labs and carries a "Labs experiment" badge. Its README is clear that scriptc is experimental and supports a subset of JavaScript, TypeScript and Node.js APIs. It is aimed at TypeScript developers who want small, self-contained binaries for CLIs, servers and embedded use, and who are willing to work within the compiler's supported subset.
How it works
The compiler runs natively on the host and bundles its own TypeScript checker and an LLVM helper. It type-checks the program, lowers statically typed code to LLVM, and links the resulting program object against a precompiled runtime pack that implements the supported Node.js APIs. Values use native representations: records have exact native layouts, strings are UTF-8 with an explicit length, and unions are tagged.
According to the platform docs, the runtime has native backends for the event loop (epoll on Linux, kqueue on macOS), the HTTP server stack, TLS and fs.watch, and its behavior is checked against real Node.js in differential test lanes on Linux, Alpine and Windows. The Windows lanes exercise net, http, https, tls, http2, dgram, dns and a native fetch implementation.
Outputs selected with --emit=ir|llvm|asm|obj need no Node installation or external toolchain. Full executables additionally need the platform linker and SDK or sysroot. Cross-compilation uses optional @scriptc/runtime-<target> packages plus zig for Linux, Windows and WASI linking, with the target chosen through SCRIPTC_TARGET.
Because static compilation is all-or-nothing per operation, scriptc includes a coverage command that reports which statements compile statically, which need the dynamic engine, and which are unsupported. Build errors use SC codes with source locations and, where available, rewrite hints.
Key features
- Type-directed native compilation: statically typed TypeScript compiles to native code through LLVM, with no JavaScript engine in fully static builds.
- Optional embedded engine:
--dynamicadds quickjs-ng for npm packages andany-typed code, with dependency JavaScript embedded at build time. - Node.js API support: supported Node APIs such as
node:httpcompile to the native runtime; a compatibility reference lists support separately for static and engine-executed code. - Coverage reports:
scriptc coverageanalyzes a program without building it and lists dynamic or unsupported sites. - Cross-compilation: Linux arm64 and x86_64 (glibc and musl), Windows x86_64 and WASI from one host using runtime packs and zig.
- WebAssembly output:
SCRIPTC_TARGET=wasm32-wasiproduces standalone WASI Preview 1 modules. - Library mode for mobile: iOS device, iOS simulator and Android arm64 targets build static archives with
--libfor an app to link. - Native FFI: compiled programs can call C ABI functions.
- Native program objects: compiler output can be fed into external builds.
- Native debugging:
--optimization=devbuilds support source breakpoints and native stack frames; macOS builds produce a.dSYMbundle. - Windows GUI subsystem:
--windows-subsystem=guiavoids an extra console window for windowed apps.
Getting started
Install with Node.js 24 or later and npm. The installed compiler itself runs natively, and standalone archives are also available from GitHub Releases:
$ npm install -g scriptcCreate hello.ts:
const who = process.argv.length > 2 ? process.argv[2] : "world";
console.log(`hello, ${who}`);Compile and run in one step:
$ scriptc run hello.ts
hello, worldOr build a standalone executable:
$ scriptc build hello.ts -o hello
$ ./hello scriptc
hello, scriptcA small HTTP server using Node APIs compiles the same way:
import { createServer } from "node:http";
const server = createServer((req, res) => {
res.setHeader("content-type", "application/json");
res.end(JSON.stringify({ path: req.url }));
});
server.listen(8080, () => {
console.log("listening on http://localhost:8080");
});$ scriptc build server.ts -o server
$ ./server
listening on http://localhost:8080For an npm dependency, enable the embedded engine:
$ npm install picocolors
$ scriptc build cli.ts --dynamic -o cli
$ ./cli
hello from scriptcOn macOS, executable builds need the Xcode Command Line Tools; the quickstart lists macOS 15+ (arm64 or x64), Linux (arm64 or x64) and Windows x64 as supported hosts.
Use cases
- Distributing CLIs: ship a TypeScript command-line tool as one binary that users can run without installing Node.js.
- Small server binaries: compile an
node:httpservice into an executable for minimal containers, including static musl builds for Alpine. - WASI modules: produce
.wasmmodules from TypeScript for WASI runtimes and embedders. - Embedding in mobile or native apps: build library-mode archives for iOS and Android with declared exports and host callbacks.
- Interop with C: call C ABI functions through native FFI, or link program objects into an existing native build.
- Gradual adoption: run
scriptc coverageon an existing codebase to see how much would compile statically before committing to it.
How it compares
The README does not compare scriptc to other tools. In the same broad category, Node.js single executable applications, Bun's and Deno's compile commands package a script with a full JavaScript runtime, which gives broad compatibility at the cost of binary size and runtime overhead. scriptc takes a different route: ahead-of-time native compilation of typed code, with an embedded engine only when you opt in. That tradeoff means much stricter language support. Projects such as AssemblyScript also compile a TypeScript-like language to WebAssembly, but use their own dialect, whereas scriptc targets standard TypeScript and Node.js APIs within its supported subset.
Things to know before adopting
- Experimental subset: the limitations page documents many unsupported forms in static code, including object-to-primitive loose equality, some generic patterns, async
yield*delegation, computed dynamic imports, and certain union and record-shape conversions. Passing a record with extra fields where a narrower shape is expected can produce anSC2002error. --dynamicis not a fallback for everything: enabling it does not add support for unsupported statically typed calls.- Toolchain requirements: executables need a platform linker and SDK; cross-linking needs zig; GNU/Linux builds require glibc 2.34 or newer.
- Debugging limits: TypeScript expression evaluation and stepping through code in the embedded engine are not supported in the debugger.
- Very new: the repository was created in July 2026, so APIs and supported features are likely to shift.
- License: Apache-2.0.
Project activity
As of October 2026 the repository has roughly 5,900 stars on GitHub. It was created on July 22, 2026, is written in TypeScript, and is licensed under Apache-2.0. The compiler is distributed on npm as scriptc and through GitHub Releases. Source code is at github.com/vercel-labs/scriptc, and documentation, including the limitations and Node.js compatibility reference, is at scriptc.dev.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/vercel-labs/scriptc
GitHub - vercel-labs/scriptc: scriptc: Compile TypeScript to Native Executables
scriptc is an experimental Apache-2.0 compiler from Vercel Labs that turns TypeScript and JavaScript into native executables and WebAssembly using type informat...
github - vercel-labs/scriptc

