Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Perry is a native TypeScript compiler that compiles TypeScript source code directly to native executables. No JavaScript runtime, no JIT warmup, no V8 — your TypeScript compiles to a real binary.

// hello.ts
console.log("Hello from Perry!");
$ perry hello.ts -o hello
$ ./hello
Hello from Perry!

Why Perry?

  • Native performance — Compiles to machine code via Cranelift. Integer-heavy code like Fibonacci runs 2x faster than Node.js.
  • Small binaries — A hello world is ~300KB. Perry detects what runtime features you use and only links what’s needed.
  • Native UI — Build desktop and mobile apps with declarative TypeScript that compiles to real AppKit, UIKit, GTK4, Win32, or DOM widgets.
  • 6 platforms — macOS, iOS, Android, Windows, Linux, and Web from the same source code.
  • Familiar ecosystem — Use npm packages like fastify, mysql2, redis, bcrypt, lodash, and more — compiled natively.
  • Zero config — Point Perry at a .ts file and get a binary. No tsconfig.json required.

What Perry Compiles

Perry supports a practical subset of TypeScript:

  • Variables, functions, classes, enums, interfaces
  • Async/await, closures, generators
  • Destructuring, spread, template literals
  • Arrays, Maps, Sets, typed arrays
  • Regular expressions, JSON, Promises
  • Module imports/exports
  • Generic type erasure

See Supported Features for the complete list.

Quick Example: Native App

import { App, Text, Button, VStack, State } from "perry/ui";

const count = State(0);

App("Counter", () =>
  VStack([
    Text(`Count: ${count.get()}`),
    Button("Increment", () => count.set(count.get() + 1)),
  ])
);
$ perry counter.ts -o counter
$ ./counter  # Opens a native macOS/Windows/Linux window

This produces a ~3MB native app with real platform widgets — no Electron, no WebView.

How It Works

TypeScript (.ts)
    ↓ Parse (SWC)
    ↓ Lower to HIR
    ↓ Transform (inline, closure conversion, async)
    ↓ Codegen (Cranelift)
    ↓ Link (system linker)
    ↓
Native Executable

Perry uses SWC for TypeScript parsing and Cranelift for native code generation. Types are erased at compile time (like tsc), and values are represented at runtime using NaN-boxing for efficient 64-bit tagged values.

Next Steps