CLI Reference
The CLI has three commands. scriptc --help prints this same surface.
$ scriptc --help
scriptc — TypeScript/JavaScript to native and WebAssembly executables (experimental)
Usage:
scriptc build <file.ts|.js> [options] compile to an executable target artifact
scriptc run <file.ts|.js> [options] compile and run
scriptc coverage <file.ts|.js> how much compiles statically, and why not
scriptc coverage <file.ts|.js> --dynamic what a --dynamic build compiles, and what still blocks it
scriptc coverage <file.ts|.js> --external-types <specifier=file.d.ts>
type-resolve an embedder-provided module for analysisscriptc build
Compiles a TypeScript (or JavaScript) entry file to a native executable, or to a WebAssembly module when the wasm32-wasi target is selected. The program is type-checked first — by the real TypeScript compiler, honoring the nearest tsconfig.json — and any construct without a lowering is a compile error with an SC-prefixed code, a code frame, and usually a rewrite hint.
$ scriptc build fib.ts -o fib
$ ./fib
832040Without -o, the executable lands in .scriptc/<name> next to the input, and the generated C translation unit is kept beside it (see --keep-c):
$ scriptc build fib.ts --emit-ir
$ ls .scriptc/
fib
fib.c
fib.ir.jsonscriptc run
build followed by executing the binary, with stdio inherited. For wasm32-wasi, the CLI starts the module through Node's WASI Preview 1 host, preopens the current working directory as /, and exposes the host's /tmp as the guest's /tmp.
$ scriptc run fib.ts
832040Note: run does not forward extra command-line arguments to the program. To pass arguments, build the executable and invoke it directly.
scriptc coverage
Analyzes the program without producing a binary and reports, statement by statement, what compiles statically, what needs the embedded dynamic engine, and what blocks the rest. With --dynamic it answers a different question: what would a --dynamic build compile, and what still blocks it. Both forms are covered in depth in Coverage Reports.
Options
-o, --out <path>- Output executable path. Default:
.scriptc/<name>next to the input file. --dynamic- Embed the dynamic engine (~620KB) so npm dependencies and
any-typed code can run. Static stays the default — without this flag, dynamic-tier sites are per-site compile errors. See npm Dependencies. --ffi <file>- Bind signature-only TypeScript declarations to native C ABI symbols and link the manifest's archive, object, and system-library inputs. See Native FFI.
--backend <c|llvm>- Code generator:
llvm(default — emits LLVM IR text, compiled by the same clang) orc(the readable debugging backend). Unset, a native build can fall back to C when the program is outside the LLVM tier. The productionwasm32-wasitarget never falls back: a missing LLVM lowering isSC3001. Use--backend cexplicitly only when inspecting generated C; on WASI that inspection lane accepts async-free programs only and reportsSC3001for coroutine-dependent surfaces. --npm-static <pkg[,pkg…]|auto>- EXPERIMENTAL. Compile the named npm packages' shipped JS statically as program modules instead of embedding them for the engine (repeatable;
autoopts in every eligible direct import). A package the preflight refuses falls back to the island with a coverage-report note. See npm Dependencies for maturity notes. --provenance-sources- EXPERIMENTAL. Compile npm dependencies from their provenance-attested source, fetched at the attested commit, as static program modules; packages without a usable attestation keep the engine path (a note, never a failure).
--external-types <specifier=file.d.ts>- Coverage only. Map an exact bare module specifier to a local declaration file supplied by an embedder. Repeat the option for multiple modules. The declaration supplies checker types so application coverage can continue; runtime imports and values remain explicit
SC1010blockers. Relative paths resolve from the current working directory. Accepted files end in.d.ts,.d.mts, or.d.cts. --sanitize- Build with AddressSanitizer plus the runtime reference-count audit — the same lane the compiler's own test corpus runs under. Useful when a program misbehaves and you want leaks or memory errors to be loud.
--emit-ir- Also write the typed IR as JSON (
<name>.ir.json) next to the executable. --keep-c/--no-keep-c- Keep (default) or delete the generated program translation unit next to the executable — the
.llfile under the default LLVM backend, or the.cunder--backend c(and when the default build fell back). The generated C is readable and annotated with source lines. --from-c- Treat the input as a C (or
.ll) file. Toolchain plumbing and debugging. These arbitrary translation units bypass the persistent artifact cache because their header dependency graph is caller-owned. -h, --help- Show usage.
Environment variables
SCRIPTC_CACHE_DIR- Override the persistent build-cache root. By default it is
$XDG_CACHE_HOME/scriptc/buildwhen that variable is set,$HOME/Library/Caches/scriptc/buildon macOS,%LOCALAPPDATA%\scriptc\cache\buildon Windows, and$HOME/.cache/scriptc/buildon other platforms. The cache stores checksum-verified, content-addressed executables, library archives, and per-flavor runtime objects. Identities include the compiler's resolved system-header dependencies and linker/assembler identities. The compiler remains required so dependency selection is rediscovered on every cache-enabled invocation. FFI builds with archive/object inputs or ambientsystem_librariesalways relink against their current dependencies while retaining runtime-object reuse. Mutable compiler input paths such asCPATHandSDKROOT, and compiler wrappers, bypass persistent artifacts and objects so dependencies rebuilt in place cannot go stale. Opaque archiver wrappers rebuild library program members and archives while retaining runtime-object reuse. Direct Clang, Apple's system Clang shim,zig cc, trusted platform archivers, andzig arretain their applicable persistent tiers. An existing POSIX override must already be private; otherwise caching is bypassed without changing the directory's permissions. SCRIPTC_NO_CACHE- Set to
1to bypass all build-cache reads and writes. An explicitly emptySCRIPTC_CACHE_DIRhas the same effect. SCRIPTC_CACHE_MAX_MB- Maximum build-cache size in megabytes. The default is
4096; the default cache is swept periodically, while an explicitly configured cap is checked after every successful cache write. Least-recently-used entries are removed when the cache exceeds the cap. SCRIPTC_CC- The C compiler to invoke.
zigccselects zig's bundled clang, which enables cross-compilation with its bundled sysroots. SCRIPTC_TARGET- Target triple for cross-compilation, e.g.
aarch64-linux-gnu.2.36,x86_64-windows-gnu, orwasm32-wasi. WASI builds default to a.wasmoutput name. See Platform Support.
$ SCRIPTC_CC=zigcc SCRIPTC_TARGET=aarch64-linux-gnu.2.36 scriptc build fib.ts -o fib-linux
$ file fib-linux
fib-linux: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 2.0.0, with debug_info, not strippedBackends
The default backend emits textual LLVM IR, compiled by the same clang that links the runtime. On native targets, a program outside that tier is never miscompiled—the build falls back to the C backend transparently and says so in one stderr line. The production wasm32-wasi target uses LLVM's 32-bit ABI path and never falls back; an LLVM coverage gap is a build diagnostic. Dynamic npm embedding is LLVM surface on every target.
The C backend is a debugging aid: deliberately readable, source-line-annotated output with differential tests against LLVM wherever the two overlap. Pin it when you want to inspect what your program became:
$ scriptc build fib.ts --backend c -o fib
$ ./fib
832040
$ head -1 fib.c
/* Generated by scriptc from fib.ts. Do not edit. */An explicit --backend llvm pins the LLVM backend and fails with diagnostic SC3001, naming the unsupported construct, instead of falling back — useful for CI lanes that must notice tier changes.