TypeScript Compiler (by LLVM)
Developed by
A native ahead-of-time (AOT) and JIT compiler for TypeScript, built on LLVM/MLIR.
It compiles .ts files directly to native executables, WebAssembly, or runs them
on the fly via a built-in JIT — no Node.js or JavaScript runtime required.
Implemented try/catch exception handling in the JIT on Windows (x64 SEH unwinding via a custom LLJIT runtime)
Migrared to LLVM 22.1.8
Migrated to Visual Studio 2026 (Windows build chain)
JavaScript Built-in objects library [Default Library repo]
Visual Studio Code project
tslang --new Test1TSLANG registered as a first-class CMake language)tslang --cmake Test1Generates a ready-to-build project (CMakeLists.txt, CMakePresets.json, main.cpp, sample .ts sources and the cmake/ TSLANG language modules). Build it with:
cd Test1
cmake --preset default && cmake --build --preset defaultlet sn: string | null = null; // Ok
let s: string = null; // errorTemplate Literal Typestype Color = "red" | "green" | "blue";
type HexColor = `#${string}`;class Point {
private x: number;
#y: number;
}
const p = new Point();
p.x // access error
p.#y // errorclass Point {
x: number;
y: number;
}
class Line {
constructor(public start: Point, public end: Point) { }
}
const l = new Line({ x: 0, y: 1 }, { x: 1.0, y: 2.0 });ifsfunction isArray(value: T): value is T {
return true;
}
function gen(t: T)
{
if (isArray(t))
{
return t.length.toString();
}
return "int";
}
const v1 = gen(23); // result: int
const v2 = gen([]); // result: 0Migrated to LLVM 19.1.3
Improved generating debug information — more info here: Wiki:How-To
tslang --di --opt_level=0 --emit=exe example.tsSee the release page for a recorded demo
Open the WASM example on Compiler Explorer
Want to chat with other members of the TypeScriptCompiler community?
…Run
tslang --emit=jit --opt --shared-libs=TypeScriptRuntime.dll example.tsResult
Department name: Accounting and Auditing
The Accounting Department meets each Monday at 10am.File hello.ts
function main() {
print("Hello World!");
}Build
tslang hello.tsResult
Hello World!JIT-compiled TypeScript can be debugged at source level with GDB — breakpoints on .ts lines,
stepping, and backtraces all work. The JIT registers every compiled object with the debugger via
the standard GDB JIT interface,
so an attached GDB picks up the DWARF debug info at runtime.
Two things are required:
--di so the compiler emits debug information;--opt (JIT debug registration is only enabled when optimizations are off).gdb --args tslang --di hello.ts
(gdb) break hello.ts:2
Make breakpoint pending on future shared library load? (y or [n]) y
(gdb) runThe breakpoint stays pending until the JIT compiles and registers your code, then binds and stops with full source context:
Thread 1 "tslang" hit Breakpoint 1, main () at hello.ts:2
2 print("Hello World!");From there the usual GDB commands work on the JIT'd frames: next, step, info locals, bt.
Notes:
(No debugging symbols found in tslang) warning at startup refers to the compiler binary
itself and is harmless — the debug info for your code arrives when the JIT registers it.debugger; TypeScript statement is also supported: it compiles to a debug trap instruction,
so execution stops exactly there when a debugger is attached. Without a debugger attached it
terminates the process with SIGTRAP, so remove it when you are done.settings set plugin.jit-loader.gdb enable.Make sure you have download
tslangfrom releases first.
The compile process may use a few environment variables so the linker can find the
runtime libraries, then invoke tslang with --emit=exe. Edit the paths to match your
checkout — the C:\dev\... / ~/dev/... values are only examples.
| Variable | Points to |
|---|---|
GC_LIB_PATH |
Boehm GC library (the garbage collector) |
LLVM_LIB_PATH |
LLVM/MLIR libraries |
TSLANG_LIB_PATH |
TSLANG runtime library |
DEFAULT_LIB_PATH |
Default library |
Build
tslang --emit=exe hello.tsRun
hello.exeResult
Hello World!Build
./tslang --emit=exe hello.ts --relocation-model=picRun
./helloResult
Hello World!Build
tslang.exe --emit=exe -mm=none -mtriple=wasm32-unknown-unknown hello.tsRun run.html
Click to expand the full run.html WebAssembly loader
How heap memory is managed is selected with -mm=:
| flag | ||
|---|---|---|
-mm=gc |
garbage collection (Boehm) | the default |
-mm=rc |
reference counting - freed as soon as the last reference goes, no collector, no libgc |
does not collect reference cycles |
-mm=none |
nothing is ever freed | short-lived programs |
-mm=gc is the default and needs no thought. -mm=rc reclaims memory deterministically and
holds close to the working set - a ray tracer that reaches 114 MB under -mm=none holds 4.1 MB,
against garbage collection's 5.8 - but objects that refer to each other in a cycle are never
freed under it, which is the same trade Swift makes with ARC.
See docs/memory-models.md for which shapes leak, which do not, and what to do about it.
Visual Studio 2026The hardcoded
C:\dev\...paths in the scripts below are examples — adjust them to your checkout location.
First, precompile dependencies
cd TypeScriptCompiler
prepare_3rdParty.batTo build TSLANG binaries:
cd TypeScriptCompiler\tslang
config_tslang_release.bat
build_tslang_release.batgcc or clangcmakeninja-buildlibtinfo-devFirst, precompile dependencies
chmod +x *.sh
cd ~/TypeScriptCompiler
./prepare_3rdParty.shTo build TSLANG binaries:
cd ~/TypeScriptCompiler/tslang
chmod +x *.sh
./config_tslang_release.sh
./build_tslang_release.shThis project is licensed under the MIT License — see the LICENSE file for details.
Issues and pull requests are welcome. See the Wiki for documentation, build notes, and how-to guides.
No open issues yet, or sync has not completed.