Guide

CLI & flags

One binary, klainmain. Point it at a file; tune the trade-offs per compile.

usage
klainmain [flags] <file.ts>

# Compile to a native binary (does NOT run it)
$ klainmain app.ts

# Compile and run in one step
$ make run FILE=app.ts

# Inspect the generated LLVM IR
$ make ir FILE=app.ts

Flags

FlagWhat it does
--emit-llvmEmit LLVM IR to stdout and stop — don't compile.
-o <name>Output binary name (default: input path without .ts).
--staticStatically link the output, for a scratch/distroless Docker image. Linux only — macOS ships no static libc, so it refuses cleanly with an explanation.
-mm <mode>Memory management: manual (default — Memory.free(x) only) or gc (Boehm GC, needs bdw-gc). Identical on Linux and macOS.
-bigint <lib>BigInt backend, linked only when used: libtommath (default) or gmp. Identical semantics — trades license/speed.
-crypto <lib>crypto.subtle backend: openssl (default) or commoncrypto (macOS only, no OpenSSL dependency).
-compat <m>strict (default — opinionated, safer-than-JS) or js (best-effort JS-faithful, e.g. global shadowing).
-regex <m>RegExp dialect: es-unicode (default) / ecmascript / es-utf16 / es-ascii / pcre.

Linking, briefly

Programs are pure libc by default. A binary only links an extra library when it actually uses the feature — libcurl for fetch/http.listen, libnghttp2 for http.listen, libpcre2 for RegExp, OpenSSL for crypto.subtle/tls. Everything else stays plain-libc, closer to typical C/C++ toolchain output than a self-contained Go binary.

Left in manual mode, a program's memory footprint is a monotonically increasing function of its runtime — a feature for short-lived CLI tools, a life choice for anything long-running. Want automatic collection? Pass -mm=gc.