You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A compiler that takes TypeScript syntax and compiles it to native machine code via LLVM.
Not a transpiler. Not a runtime. tscc produces standalone native binaries from .ts files.
tscc run examples/hello.ts
Performance
All benchmarks on Apple Silicon M3. Best of 3 runs.
Recursive Fibonacci — fib(40)
Runtime
Time
Relative
Memory
tscc
0.28s
1.0x
1.2 MB
C (cc -O3)
0.28s
1.0x
1.2 MB
Rust (rustc -O, i64)
0.28s
1.0x
1.4 MB
Rust (rustc -O, f64)
0.41s
1.5x slower
1.4 MB
Bun 1.3
0.48s
1.7x slower
27 MB
Node 25
0.79s
2.8x slower
49 MB
Loop Sum — sum(0..1_000_000_000)
Runtime
Time
Relative
tscc
< 0.01s
--
Rust (rustc -O)
< 0.01s
--
Bun 1.3
0.88s
--
Node 25
1.47s
--
Both tscc and Rust produce effectively instant results — LLVM optimizes the entire loop into a closed-form computation at compile time.
Why is tscc fast?
LLVM O3 — Full optimization pipeline (loop vectorization, SLP vectorization, function inlining, dead code elimination)
Native CPU targeting — Generates code tuned for the exact CPU (-mcpu=native)
Integer narrowing — Analysis pass detects when number values can compile as i64 instead of f64, enabling LLVM's integer-specific optimizations (accumulator transformation, strength reduction)
No runtime overhead — No JIT warmup, no garbage collector, no event loop. Just a native binary
Tiny binaries — fib(40) compiles to a 37 KB binary (vs 441 KB for Rust)
Compilation Speed
Mode
Time
Optimized (O3)
~90ms
Debug (no optimization)
~80ms
Install
Requires LLVM 18 and Rust.
# Install LLVM 18
brew install llvm@18
# Set environment variables (add to your shell profile)export LLVM_SYS_180_PREFIX=/opt/homebrew/opt/llvm@18
export LIBRARY_PATH="/opt/homebrew/lib:$LIBRARY_PATH"# Build tscc
cargo install --path .
Usage
# Compile and run
tscc run file.ts
# Compile to binary
tscc build file.ts # outputs ./file
tscc build file.ts -o output # custom output path# Flags
tscc run file.ts --benchmark # time execution
tscc build file.ts --debug # skip optimization (faster compile)
tscc build file.ts --emit-ir # print LLVM IR
TypeScript source
|
+- Lexer -------- Hand-written scanner
+- Parser ------- Recursive descent + Pratt precedence
+- Type Checker -- Structural typing, inference
+- Codegen ------ LLVM IR via inkwell
+- Optimizer ---- LLVM O3 + native CPU targeting
+- Linker ------- Links with pre-compiled runtime
|
Native binary
Written in Rust. Single crate. ~9,000 lines of Rust + ~285 lines of C runtime.
The runtime (runtime/runtime.c) provides print functions, string operations, math functions, and array support. It is compiled once at cargo build time and embedded directly into the tscc binary — no C toolchain is required on the user's machine to compile TypeScript files.
Status
Early stage. 195 tests passing, 44 pending. The goal is drop-in compatibility with existing TypeScript projects. Currently covers the core language features needed for compute-heavy programs.
TypeScript Feature Coverage
195 passing / 44 not yet implemented — 82% of test suite
Literals & Primitives
Feature
Status
Test
Integer literals
✅
console.log(42)
Float literals
✅
console.log(3.14)
Negative numbers
✅
console.log(-7)
Zero
✅
console.log(0)
Large integers
✅
console.log(1000000)
String (double quotes)
✅
console.log("hello")
String (single quotes)
✅
console.log('world')
Empty string
✅
console.log("")
Boolean true
✅
console.log(true)
Boolean false
✅
console.log(false)
null
✅
console.log(null)
undefined
✅
console.log(undefined)
BigInt literals
❌
9007199254740993n
Variables
Feature
Status
Test
let with number
✅
let x = 10
let with string
✅
let s = "hi"
let with boolean
✅
let b = true
const
✅
const x = 99
Type annotations
✅
let x: number = 5
String type annotation
✅
let s: string = "typed"
Boolean type annotation
✅
let b: boolean = false
Reassignment
✅
x = 2
Multiple variables
✅
let a = 1; let b = 2
Uninitialized let
✅
let x: number (defaults to 0)
Optional semicolons
✅
let x = 42
var declarations
✅
var x = 42
Arithmetic Operators
Feature
Status
Test
Addition +
✅
2 + 3
Subtraction -
✅
10 - 4
Multiplication *
✅
3 * 7
Division /
✅
10 / 4
Modulo %
✅
10 % 3
Exponentiation **
✅
2 ** 10
Operator precedence
✅
2 + 3 * 4 = 14
Parenthesized expressions
✅
(2 + 3) * 4 = 20
Postfix ++ / --
✅
x++, x--
Prefix ++ / --
✅
++x, --x
Unary negate
✅
-x
+=-=*=/=
✅
x += 3
Comparison Operators
Feature
Status
Test
<><=>=
✅
1 < 2, 5 > 3
==!=
✅
5 == 5, 5 != 6
===!==
✅
5 === 5, 5 !== 5
Boolean equality
✅
true == true
Logical Operators
Feature
Status
Test
&&
✅
true && true
||
✅
false || true
!
✅
!true
Complex logical
✅
true && !false || false
Numeric && / ||
✅
1 && 1, 0 || 1
Nullish coalescing ??
✅
null ?? 42
Optional chaining ?.
✅
obj?.a
Strings
Feature
Status
Test
Concatenation +
✅
"hello" + " world"
String + number
✅
"value: " + 42
String + boolean
✅
"it is " + true
.length
✅
"hello".length
.toUpperCase()
✅
"hello".toUpperCase()
.toLowerCase()
✅
"HELLO".toLowerCase()
.charAt()
✅
"hello".charAt(1)
.indexOf()
✅
"hello world".indexOf("world")
.includes()
✅
"hello world".includes("world")
.substring()
✅
"hello world".substring(0, 5)
.slice()
✅
"hello world".slice(-5)
.trim()
✅
" hello ".trim()
Template literals
✅
`value is ${x}`
Chained methods
✅
" Hello ".trim().toUpperCase()
.startsWith()
✅
"hello".startsWith("he")
.endsWith()
✅
"hello".endsWith("lo")
.repeat()
✅
"ab".repeat(3)
.split()
❌
"a,b,c".split(",")
.replace()
✅
"hello".replace("l", "r")
.padStart()
✅
"5".padStart(3, "0")
Control Flow
Feature
Status
Test
if
✅
if (true) { ... }
if/else
✅
if (x) { ... } else { ... }
if/else if/else
✅
chained conditions
while
✅
while (i < 5) { ... }
for
✅
for (let i = 0; i < n; i++)
Nested loops
✅
for { for { ... } }
Block scoping
✅
{ let y = 2 }
break
✅
if (i == 5) break
continue
✅
if (i == 2) continue
Ternary ? :
✅
true ? 1 : 2
do...while
✅
do { i++ } while (i < 5)
switch/case
✅
switch (x) { case 1: ... }
for...of
✅
for (let x of arr)
for...in
❌
for (let key in obj)
Labeled statements
❌
outer: for (...)
Functions
Feature
Status
Test
Declarations
✅
function add(a, b) { return a + b }
Return values
✅
return a + b
Multiple params
✅
function f(a, b, c)
String params/returns
✅
function hello(name: string): string
Boolean returns
✅
function isPositive(n): boolean
Recursion
✅
function fib(n) { ... fib(n-1) }
Mutual calls
✅
double(double(x))
Local variables
✅
let result = x * 2
Void functions
✅
function sayHi(): void
Arrow (expression)
✅
let add = (a, b) => a + b
Arrow (block body)
✅
let f = (x) => { return x }
Function hoisting
❌
calling before declaration
Closures
✅
capturing outer variables
Default parameters
✅
function f(x = 10)
Rest parameters
✅
function f(...args: number[])
Spread syntax
✅
[...arr, 4, 5]
Function expressions
❌
let f = function() {}
Arrays
Feature
Status
Test
Literals
✅
[1, 2, 3]
Index access
✅
arr[1]
.length
✅
arr.length
.push()
✅
arr.push(4)
.pop()
✅
arr.pop()
.map()
✅
arr.map(x => x * 2)
.filter()
✅
arr.filter(x => x > 2)
.reduce()
✅
arr.reduce((a, b) => a + b, 0)
.forEach()
✅
arr.forEach(x => console.log(x))
Math Standard Library
Feature
Status
Test
Math.floor()
✅
Math.floor(3.7)
Math.ceil()
✅
Math.ceil(3.2)
Math.round()
✅
Math.round(3.5)
Math.abs()
✅
Math.abs(-5)
Math.sqrt()
✅
Math.sqrt(9)
Math.pow()
✅
Math.pow(2, 10)
Math.min() / Math.max()
✅
Math.min(3, 7)
Math.sin() / Math.cos() / Math.tan()
✅
trig functions
Math.log() / Math.exp()
✅
Math.log(Math.E)
Math.random()
✅
returns [0, 1)
Math.PI / Math.E
✅
constants
Console & Globals
Feature
Status
Test
console.log()
✅
single and multiple args
console.error()
✅
writes to stderr
console.warn()
✅
writes to stderr
typeof
✅
typeof 42 = "number"
parseInt()
✅
parseInt("42")
parseFloat()
✅
parseFloat("3.14")
Modules
Feature
Status
Test
export function
✅
export function square(x) {}
import { name }
✅
import { square } from "./math"
Multiple imports
✅
import { a, b } from "./utils"
Import aliasing as
❌
import { add as sum }
Default export
❌
export default 42
import * as
❌
import * as math from "./math"
Re-exports
❌
export { foo } from "./bar"
Objects & Classes
Feature
Status
Test
Object literals
✅
{ x: 1, y: 2 }
Property access
✅
obj.x
Bracket access
✅
obj["x"]
Object methods
✅
obj.getX()
console.log(obj)
✅
{ name: 'Kian', age: 19 }
Class declarations
✅
class Point { ... }
new + constructor
✅
new Point(3, 4)
Class methods
✅
p.toString()
Class inheritance
✅
class Dog extends Animal
Interfaces
✅
interface Point { x: number }
Array destructuring
✅
let [a, b] = [1, 2]
Object destructuring
✅
let { x, y } = { x: 1, y: 2 }
Type System
Feature
Status
Test
Type annotations
✅
let x: number, function f(): string
Type inference
✅
let x = 42 (inferred as number)
Union types
❌
string | number
Type aliases
❌
type ID = string | number
Enums (numeric)
❌
enum Color { Red, Green }
Enums (string)
❌
enum Direction { Up = "UP" }
Generics
❌
function identity<T>(x: T): T
Generic constraints
❌
<T extends { length: number }>
Tuple types
❌
[number, string]
Type assertions
❌
x as string
Type narrowing
❌
if (typeof val === "string")
String literal types
❌
type Dir = "up" | "down"
Intersection types
❌
Named & Aged
readonly
❌
readonly host: string
keyof
❌
keyof Point
Conditional types
❌
T extends number ? "yes" : "no"
Mapped types
❌
{ [P in keyof T]: T[P] }
typeof in type position
❌
let y: typeof x
satisfies
❌
"red" satisfies Colors
as const
❌
[1, 2, 3] as const
Error Handling & Async
Feature
Status
Test
try/catch
❌
try { throw new Error() } catch (e) {}
try/finally
❌
try { ... } finally { ... }
async/await
❌
async function f() { await ... }
Promises
❌
Promise.resolve(42)
Built-in Objects
Feature
Status
Test
JSON.stringify()
❌
JSON.stringify({ a: 1 })
Map
❌
new Map()
Set
❌
new Set([1, 2, 3])
RegExp
❌
/hello/.test("hello world")
Number.isInteger()
❌
Number.isInteger(42)
Number.isFinite()
❌
Number.isFinite(42)
Number.isNaN()
❌
Number.isNaN(NaN)
.toFixed()
❌
(3.14).toFixed(2)
Advanced Features
Feature
Status
Test
Namespaces
❌
namespace Util { ... }
Decorators
❌
@log
Symbols
❌
Symbol("foo")
Generators
❌
function* range()
License
MIT
About
A compiler that compiles TypeScript to native machine code via LLVM