deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Vercel's ScriptC compiles TypeScript to standalone native binaries without Node.js

Vercel Labs has open-sourced ScriptC, an experimental compiler that turns TypeScript into standalone native executables, plus C, LLVM IR and WebAssembly, removing the need to ship a JavaScript runtime.

Vercel's ScriptC compiles TypeScript to standalone native binaries without Node.js

Vercel Labs has open-sourced ScriptC, an experimental compiler that translates TypeScript and JavaScript into standalone native executables. According to a dev.to article introducing the project, the tool can also emit a typed intermediate representation, readable C, LLVM IR and WebAssembly, and the repository lives on GitHub under an Apache-2.0 licence.

The problem ScriptC targets

TypeScript has spread across web front ends, backend services and CLI tooling, but it still executes on top of a JavaScript runtime. Shipping a TypeScript CLI or microservice today means packaging Node.js, Deno or Bun alongside the code. The dev.to article frames this as three recurring costs: JIT engines need tens of milliseconds to initialise before user code runs; single-binary bundlers regularly produce executables in the 40–90 MB range because they carry V8 and the Node runtime; and small helper utilities or serverless functions burn tens of megabytes of baseline memory before a single line of business logic executes. ScriptC is an attempt to treat TypeScript as a language that can be compiled ahead of time, sidestepping those costs entirely.

A multi-stage pipeline built on the official compiler

ScriptC does not invent a new language. It reuses the official TypeScript compiler for parsing and type checking, then lowers the resulting tree through progressively lower-level tiers. Source code is first turned into a typed JSON intermediate representation, which can then be translated into readable C, textual LLVM IR, or WebAssembly targeting WASI Preview 1. The C and LLVM paths continue down to native assembly and object files before linking into a final executable.

Each stage can be inspected via --emit flags — ir, c, llvm, asm and obj — which, per the article, makes the lowering process transparent rather than a black box.

Node APIs mapped to system calls

Beyond pure computation, ScriptC implements standard Node.js APIs natively. An HTTP server written with node:http and compiled via scriptc build links its event loop directly against native socket primitives instead of routing through V8. In a fully static build, the binary links only a minimal runtime pack for memory management and core primitives — no Node.js, no V8, no JIT. The article claims such binaries start in microseconds and use negligible memory, though these figures are the project's own positioning rather than independent benchmarks.

Diagnostics and a dynamic fallback

Because TypeScript codebases often lean on dynamic patterns, not everything can be compiled statically ahead of time. ScriptC ships a coverage tool: running scriptc coverage app.ts reports what percentage of the AST compiles statically and emits diagnostic codes for dynamic sites that would require reflection.

For code that cannot be lowered — including third-party npm packages or any-heavy codebases — a --dynamic flag embeds QuickJS-NG, an ultra-lightweight JavaScript engine, directly into the executable. That preserves compatibility with the existing ecosystem without dragging in a full Node runtime.

WebAssembly as a cross-compile target

By using Zig as a cross-target linker driver, configured through SCRIPTC_CC=zigcc, ScriptC can cross-compile TypeScript into wasm32-wasi modules. Those outputs can run in any WASI-capable runtime or edge worker, giving the same source two deployment paths: bare-metal native binaries and portable wasm.

Trying it out

The compiler driver itself requires Node.js 24 or newer and installs globally with npm install -g scriptc. A basic workflow is a single command: scriptc build hello.ts -o hello produces an executable that runs on compatible machines with no Node.js installed. As with any young research project, expect rough edges.

Why it matters

ScriptC is explicitly positioned as an experimental research effort, and a single dev.to write-up is the only available account of its capabilities — numbers on binary size, startup time and memory should be read as claims to verify rather than settled results. Even so, the direction is significant. Decoupling TypeScript from the JavaScript runtime would reshape how CLIs, microservices and edge functions are built and deployed: smaller artefacts, faster cold starts and lower memory floors. The coverage tooling and QuickJS fallback also show a realistic path for migrating existing code rather than demanding greenfield projects. If the approach matures, TypeScript stops being a layer that must be interpreted and becomes a systems language in its own right.

  • #typescript
  • #compilers
  • #vercel
  • #webassembly
  • #native-binaries