Scriptc Bets TypeScript Is Static Enough to Go Native
Vercel Labs' engine-free compiler ships 200KB binaries — until your npm dependencies drag in an interpreter.
TypeScript-to-native compilation has a graveyard's worth of prior attempts, which is why the interesting thing about Scriptc isn't the pitch — it's the contract. Vercel Labs' new compiler takes ordinary TypeScript, type-checks it with the real tsc, lowers it to a typed IR, and emits self-contained native binaries through LLVM or C: no Node, no V8, no JavaScript engine in the output. The project claims 170–200KB static binaries, ~2.4ms startup, and 1–4MB resident memory, versus roughly 47ms startup for Node and 60–100MB for a Node single-executable build. Those numbers are self-reported and measured on Apple Silicon, but even discounted heavily, they're a different category of artifact than anything bun build --compile or Node SEA produces, because those tools bundle the engine; Scriptc's whole premise is deleting it.
The three-tier contract is the actual innovation
Every previous attempt at this problem died on the same rock: JavaScript is dynamic, and TypeScript's types are a fiction the runtime never checks. AssemblyScript solved it by defining a stricter dialect — fine, but then you're not writing TypeScript anymore. Meta's Static Hermes leans on Flow-style soundness. Porffor, the most credible independent effort, compiles real JS ahead-of-time but is still working through spec conformance, one heroic solo developer at a time.
Scriptc's answer is to stop pretending the problem doesn't exist and instead make it legible. Every construct in your program lands in one of three explicit tiers: compiled statically to native code (the default), executed dynamically by an embedded quickjs-ng engine (~620KB, opt-in via --dynamic), or rejected outright with a specific error code and a rewrite hint. A scriptc coverage command tells you exactly what percentage of your statements compile statically and what's blocking the rest. Values crossing from the dynamic tier back into static code get runtime-validated, so a lying .d.ts throws a catchable TypeError instead of corrupting memory. JSON.parse(x) as Config becomes a checked cast that names the offending path when it fails.
That legibility is genuinely new. Nothing silently miscompiles, nothing silently falls back to an interpreter, and the compatibility bar is enforced mechanically: an 800+ program corpus runs under both Node and the native binary, and stdout, stderr, and exit codes must match byte-for-byte, with the whole suite re-run under AddressSanitizer. Whether the implementation lives up to that bar is a separate question, but as a design, it's the most honest framing of the static-TypeScript problem anyone has shipped.
One disambiguation, because the timing invites confusion: this is unrelated to TypeScript 7's Go-based compiler, which hit release candidate in June. Microsoft rewrote the compiler to run natively so your type-checks get ~10x faster; your code still runs on a JS engine. Scriptc compiles your program to native code. Same word, opposite ends of the toolchain.
Where the promise runs out
The catch is the npm ecosystem, and it's a big one. The static tier covers a substantial surface — classes, closures, async/await on stackful fibers, generics via monomorphization, most of Node's fs/path/process/http/tls API, even fetch over a vendored TLS stack. But npm dependencies ship JavaScript, not TypeScript, so they run in the QuickJS tier. Hacker News commenters with dynamic-language-runtime experience were blunt about what that means: QuickJS is dramatically slower than V8's JIT, and real-world TypeScript apps are mostly dependencies. Add that all numbers are currently f64 — integer inference is "on the roadmap" — and the performance story for anything beyond dependency-light code gets murky fast.
Then there's the elephant: observers totted up roughly 918,000 lines of code landed in a single week on a repo that's five days old, which points unambiguously at coding agents doing the bulk of the writing. Simon Willison's contribution to the project was a pull request stripping AI-flavored marketing prose from the docs. The differential-testing and ASan gates are exactly the right harness for agent-written code — arguably the only way a compiler like this gets built in a week — but a 900KLOC codebase that no human has fully read, published under a Vercel Labs banner with a well-known pattern of splashy experiments going quiet, is a real maintenance risk. This is v0.0.x software in every sense.
What to actually do with it
If you write CLI tools in TypeScript, this is worth an afternoon. npm install -g scriptc, then scriptc build tool.ts, ideally on macOS arm64 (the primary platform; Linux and Windows go through cross-compilation lanes). Run scriptc coverage first — it'll tell you immediately whether your code lives in the fast tier or whether you're really shipping a QuickJS app with extra steps. The sweet spot is exactly the niche where people currently give up and rewrite in Go: internal CLIs, git hooks, small servers, anything where Node's ~50ms startup and 100MB memory floor is embarrassing but a rewrite isn't worth it. A 200KB binary that starts in single-digit milliseconds is also an obvious fit for serverless cold starts, which is presumably why Vercel is funding this at all.
What you shouldn't do is bet a product on it. The right frame is Static Hermes circa 2023: a credible research artifact that tells you where the ecosystem is heading. And the direction matters more than the artifact. Between Microsoft porting the type-checker to Go and Vercel compiling user code to native, the "TypeScript is just linting for JavaScript" era is visibly ending — types are becoming load-bearing for performance, not just for editors. If Scriptc's coverage-report model survives even if the project doesn't, it will have moved the field: the next serious attempt at static TypeScript now has a contract to beat, not just a benchmark.
Sources & further reading
- vercel-labs/scriptc: TypeScript-to-Native Compiler — github.com
- Scriptc by Vercel: TypeScript-to-Native compiler, no JavaScript engine in binary — news.ycombinator.com
- scriptc - TypeScript-to-Native Compiler — scriptc.dev
- TypeScript 7.0 RC Moves Microsoft's Go Rewrite Into the Mainline Compiler — visualstudiomagazine.com
Rachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.
Discussion 0
No comments yet
Be the first to weigh in.