Does Vercel’s scriptc Deliver Native TypeScript Binaries? The Perry Claim
The article examines Vercel Labs’ scriptc tool that compiles TypeScript into a ~178 KB native executable with ~2 ms startup, compares its compilation pipeline, runtime implementation, and feature set to the earlier Perry project, and evaluates the plagiarism accusations by analyzing code differences, release timelines, and architectural choices.
If TypeScript could be compiled directly to a native binary like Go or Rust, would you use it? Vercel Labs recently open‑sourced scriptc, which claims to do exactly that. Building a simple fib.ts with scriptc build fib.ts produces an approximately 178 KB standalone executable that starts in about 2 ms.
Some community members quickly accused scriptc of copying the earlier Perry project, which also aimed to compile TypeScript to a native program without relying on Node.js, V8, or Electron.
While Perry predates scriptc, the publicly available evidence does not conclusively prove plagiarism.
What scriptc actually does
scriptc is not a bundler like pkg or Node.js SEA. Traditional single‑file bundlers embed the JavaScript code together with the Node.js runtime, resulting in a convenient distribution file that still contains a JavaScript engine. scriptc’s static mode attempts to translate TypeScript code into true native machine code, producing an artifact that contains no Node.js, V8, or other JavaScript engine.
The compilation pipeline consists of four steps:
Use the official TypeScript compiler for parsing and type checking.
Convert the code into a typed intermediate representation.
Generate machine code via LLVM by default, while retaining a C backend as a reference implementation.
Pass the C backend output to Clang for final linking into a native executable.
The real difficulty lies not in turning numbers into instructions but in faithfully reproducing JavaScript semantics: preserving UTF‑16 string behavior, maintaining array/Map/Set ordering and identity, supporting closures, exceptions, async/await, and the event loop. scriptc implements a C runtime and uses differential testing to compare program output, error messages, and exit codes between Node.js and the native binary.
When static compilation cannot handle certain npm dependencies or any code, developers can enable --dynamic to embed quickjs‑ng in the binary. The tool classifies results into three categories:
Static compilation : no JavaScript engine bundled.
Dynamic execution : the embedded engine handles parts that cannot be statically compiled.
Compilation rejected : specific error codes and remediation hints are emitted.
This nuanced boundary is more honest than claiming “any TypeScript can become machine code.”
Perry arrived earlier
The criticism has a timeline basis: Perry’s GitHub repository was created in January 2026 with its first public commit the same month, whereas scriptc’s npm package appeared on July 13 and its repository went public on July 22, roughly six months later.
Both projects share similar messaging: they emphasize direct TypeScript‑to‑native compilation, independence from Node.js and V8, small binary size, low startup latency, and single‑file distribution, while also filling common Node.js API and npm compatibility gaps.
It is understandable that Perry’s community feels uneasy when a larger company releases a similar project, a pattern not uncommon in open‑source.
Code‑level differences
Three major distinctions emerge from a side‑by‑side code inspection:
1. Compiler front‑end. scriptc directly invokes the TypeScript compiler API (via tsc) to obtain parsing, type‑checking, and type‑narrowing results, then generates its own typed IR. Perry’s core is written in Rust, using SWC to parse TypeScript and maintaining its own type system, HIR, and transformation steps.
2. Runtime strategy. scriptc’s static runtime is implemented in C with reference counting and cycle collection; its dynamic mode embeds quickjs‑ng. Perry’s compiler and runtime are Rust‑based, employing a custom garbage collector, the Rust standard library, and many native extensions.
3. Product scope. scriptc currently targets CLI and server‑side programs, focusing on Node.js behavior fidelity, static coverage, and diagnosability. Perry has expanded to desktop, mobile, watch, TV, WebAssembly, and native UI components, indicating a broader ambition.
Both follow the typical native compiler stages—parsing, type representation, lowering, code generation, linking—and both rely on LLVM, but similarity in architecture alone does not prove copying.
Confirmed observations:
Perry was publicly released earlier and deserves recognition as the pioneer.
The two repositories differ markedly in implementation language, front‑end design, and runtime strategy.
Without concrete evidence of code similarity, license violation, or shared commit history, the “pure copy” accusation remains an emotional claim.
The next path for TypeScript
The debate reflects a broader shift in the TypeScript ecosystem. Historically, TypeScript compiles to JavaScript, leaving runtime concerns to Node.js, Bun, or browsers. Both scriptc and Perry challenge this assumption by asking whether sufficiently typed code can be compiled directly to machine code.
If successful, native compilation could benefit command‑line tools, serverless functions, small services, and edge workloads by offering faster startup, lower memory usage, and eliminating the need to ship a full JavaScript runtime.
However, Node.js’s dynamic capabilities, native extensions, complex npm dependencies, and long‑standing compatibility remain significant engineering hurdles. scriptc is still at version 0.0.x and primarily supports macOS arm64, while Perry’s coverage is broader but still far from full Node.js compatibility.
In my view, scriptc’s greatest contribution is not inventing native TypeScript compilation but bringing the concept into the spotlight through Vercel Labs’ involvement, prompting more scrutiny and testing of this niche approach.
Both projects merit visibility and independent evaluation based on implementation quality, compatibility, and performance rather than being reduced to a simplistic “who copied whom” narrative.
The ultimate verdict will be decided by real‑world projects, sustained maintenance, and rigorous compatibility testing.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
