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).
--staticBuild a self-contained binary — the non-system libraries link statically instead of as dynamic dependencies. Linux: fully static (incl. libc), for a scratch/distroless image. Windows: statically links the mingw runtime, pcre2, and the libcurl chain, so the .exe needs no DLLs beside it (the UCRT and core Win32 DLLs stay dynamic — they ship with Windows 10/11). macOS: refuses cleanly (no static libSystem). Without it, builds are dynamic on every platform.
-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. By default those are dynamic dependencies — closer to typical C/C++ toolchain output than a self-contained Go binary — so a dynamic binary assumes the target machine has them (the same assumption on every platform: a Linux binary needs libcurl.so present, a Windows one needs the DLL).

Pass --static when you want a single self-contained binary that runs anywhere with no external dependency. That's the flag to build a distributable CLI/TUI tool or a desktop app — it's how the showcase apps are built. Without it, distributing a dynamic build is a packaging step: on Linux/macOS you declare the dependency (apt/Homebrew), on Windows you bundle the required DLLs alongside the .exe (or, where a license forbids redistribution, point users to the vendor's download).

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.