Compile TypeScript to Native.
One Codebase, Every Platform.
Perry compiles TypeScript to native GUI and CLI apps on macOS, iPadOS, iOS, Android, Linux, Windows, watchOS, tvOS, HarmonyOS, WebAssembly, and the Web. No runtime. No Electron. Just native binaries.
$ perry compile main.ts
Compiling main.ts...
✓ Compiled executable: main (2.3 MB)
$ ./main
Hello, World!
Real apps, compiled from TypeScript with Perry.
Why Perry?
Everything you need to compile TypeScript to native applications
No Runtime Required
Produces standalone native executables. No Node.js, no V8, no runtime dependencies. Just a single binary that runs anywhere.
Fast Compilation
Direct TypeScript to native code compilation using SWC for parsing and LLVM for optimized code generation. No intermediate JavaScript.
Small Binaries
Output binaries are typically 2-5MB. With optional V8 runtime for JS npm packages, 15-20MB. Ship less, deploy faster.
Deterministic Builds
Same input, same binary. Reproducible across machines, across CI runs, across teams. No mystery rebuilds.
Comprehensive Standard Library
Built-in native implementations of fs, path, crypto, os, Buffer, child_process, and more. Use familiar Node.js APIs.
Real npm Packages
axios, zod, express, fastify, and hono compile to native binaries. Pure-JavaScript packages run on an optional embedded runtime — self-contained, with no node_modules at runtime.
35+ Native UI Widgets
Buttons, tables, date pickers, drag & drop, charts, maps, command palettes, QR codes, rich text, and more — all compiling to real platform widgets via AppKit, UIKit, GTK4, Win32 (Fluent/Mica), and JNI.
Compile-Time Plugin System
Modules compose at build time — no runtime plugin overhead, no IPC boundaries. Your dependencies become direct native function calls in the final binary.
True Multi-Threading
Real OS threads with parallelMap, parallelFilter, and spawn. Compile-time safety rejects mutable captures — no SharedArrayBuffer, no workers, just threads.
Compile-Time i18n
Automatic string extraction, CLDR plural rules for 30+ locales, compile-time validation. Translations baked into the binary with near-zero runtime lookup.
Go deeper: how Perry compiles TypeScript to a binary, what makes it a TypeScript native compiler, and how it stacks up against Electron alternatives.
See What People Build
Real native apps, compiled from TypeScript. No Electron, no web views — just native UI on every platform.
Mango
Native MongoDB GUI — built entirely in TypeScript


Hone
Native AI-powered code editor — TypeScript to native binary

Native on Every Platform
Perry compiles your TypeScript to native UI frameworks, WebAssembly, and JavaScript — not web views, not Electron. Real native widgets on every platform, plus the web.
macOS
AppKit
iOS
UIKit
iPadOS
UIKit
Android
Views
Linux
GTK4
Windows
Win32
watchOS
SwiftUI
tvOS
SwiftUI
WASM
WebAssembly
Web
JavaScript
From Code to App Store
Perry doesn't just compile your app — it gets it into your users' hands.
Build & Sign
Cross-platform builds from one command. Code signing for macOS, iOS, Android, and Windows handled for you. No wrestling with Xcode provisioning profiles or Android keystores.
Distribute
Push to the App Store, Play Store, or ship direct downloads. Perry Publish handles packaging, notarization, and submission.
Verify
Powered by Geisterhand. Automated UI testing across all 6 platforms. Know your app works everywhere before your users tell you it doesn't.
Free for open-source projects. Plans for teams → /publish
The only framework that checks every box
TypeScript compiled to native code. Real platform widgets. No runtime overhead.
| Framework | Language | Native Code | Native Widgets | Runtime Overhead |
|---|---|---|---|---|
Perry★AOT compiled to native binary | TypeScript | None | ||
React NativeJIT / interpreted at runtime | JS / TypeScript | Hermes / V8 + Bridge | ||
FlutterAOT compiled, custom renderer | Dart | Dart VM + Skia engine | ||
KMP + ComposeJVM on Android, native on iOS | Kotlin | Partial | Kotlin runtime + Skia | |
Swift for AndroidNative binary, no shared UI | Swift | No shared UI | Swift runtime on Android | |
.NET MAUIPartial AOT via Mono | C# | Partial | .NET / Mono runtime | |
NativeScriptJS runtime, native widget access | JS / TypeScript | V8 / JavaScriptCore | ||
IonicWeb app in native wrapper | JS / TypeScript | WebView + Capacitor |
Write TypeScript, Ship Native
Use familiar TypeScript syntax and APIs. Perry handles the rest.
// hello.tsconst greeting = "Hello, World!";console.log(greeting); // Compiles to ~2MB native executable// No runtime needed!Performance Comparison
Native compilation delivers unmatched efficiency
| Metric | Perry | Node.js | Bun |
|---|---|---|---|
| Binary Size | 2-5 MB | ~80 MB | ~90 MB |
| Startup Time | ~1 ms | ~30 ms | ~10 ms |
| Runtime Dependencies | None | Node.js | Bun |
| Memory Overhead | Minimal | V8 + GC | JSC + GC |
Benchmark Results: Up to 18x Faster
Perry v0.5.279 vs Node.js v25 — RUNS=11 median, Apple M1 Max (lower is better)
Get Started
Install Perry and start compiling TypeScript to native executables
1Installation
$ brew tap PerryTS/perry$ brew install perryRequires Homebrew. Supports macOS arm64 and x86_64.
2Usage
perry compile main.tsCompiles main.ts to a native executable
perry compile main.ts -o myappSpecify the output executable name
perry compile main.ts --enable-js-runtimeEnable V8 for JavaScript npm package compatibility
perry check ./srcValidate TypeScript code for native compilation
Feature Support
Comprehensive TypeScript and Node.js API coverage
Core Language
- Numbers64-bit floating point (f64)
- StringsUTF-8, all common methods
- Booleanstrue/false, logical operators
- ArraysTyped and mixed-type arrays
- ObjectsObject literals and field access
- BigInt256-bit integer support
- EnumsNumeric and string enums
Functions
- Function DeclarationNamed functions
- Arrow Functions() => {} syntax
- Default ParametersParameters with defaults
- Rest Parameters...args syntax
- ClosuresIncluding mutable captures
- Higher-Order FunctionsFunctions as arguments/returns
- Async/AwaitAsync function support
Classes
- Class DeclarationBasic class syntax
- ConstructorsWith parameters
- Private Fields (#)ES2022 #privateField syntax
- Static Methods/FieldsClass-level members
- Getters/Settersget/set accessors
- Inheritanceextends keyword
- Super Callssuper() constructor calls
Type System
- Type AnnotationsExplicit type declarations
- Type InferenceAutomatic type detection
- GenericsMonomorphization (like Rust)
- InterfacesInterface declarations
- Union Typesstring | number support
- Type Guardstypeof operator
- Type Aliasestype X = ... declarations
Standard Library
- fsreadFileSync, writeFileSync, existsSync, etc.
- pathjoin, dirname, basename, extname, resolve
- cryptorandomBytes, randomUUID, sha256, md5
- osplatform, arch, hostname, memory info
- Bufferfrom, alloc, toString, slice, copy
- child_processexecSync, spawnSync
- JSON/Math/DateFull implementations
30+ Native npm Packages
Popular npm packages reimplemented in native Rust. No npm install, no node_modules, just fast native code.
Database
Security
HTTP
Data Processing
Date & Time
Utilities
How It Works
From TypeScript source to native executable in seconds
Want to know how the compiler works under the hood? Compiler internals
Deep dive: TypeScript on LLVM — monomorphization, NaN-boxing, and why Perry left Cranelift.
Frequently Asked Questions
Everything people ask before compiling their first binary
Does Perry need Node.js or a runtime?
No. Perry compiles TypeScript ahead of time to a standalone native executable. The binary runs without Node.js, Bun, Deno, or any JavaScript runtime installed on the machine. For npm packages that can't compile natively yet, an optional embedded V8 fallback is available via --enable-js-runtime.
How big are the compiled binaries?
A hello-world binary is around 330 KB. Typical CLI tools land at 2–5 MB. Full applications that pull in large frameworks (Fastify, mysql2, etc.) are around 48 MB — still far below the ~80–150 MB an Electron app or runtime-embedded binary starts at.
Can I use npm packages?
Yes. Pure TypeScript/JavaScript packages compile natively via perry.compilePackages — axios, zod v4, express, fastify, and hono compile and run today. Packages that need full JS engine semantics can run through the optional V8 fallback with --enable-js-runtime.
Which platforms does Perry support?
Ten compilation targets: macOS, iOS, iPadOS, Android, Linux, Windows, watchOS, tvOS, WebAssembly, and Web/JS. GUI apps use native platform widgets — AppKit, UIKit, GTK4, Win32, and Android via JNI.
Is Perry free and open source?
Yes. The compiler is free and open source. Compiling and running locally costs nothing and requires no account. Perry Publish — the hosted build, signing, and store-submission pipeline — has a free tier (15 publishes per month) and a Pro plan.
How is Perry different from Bun or Deno compile?
Bun and Deno bundle your JavaScript together with their runtime into one file — a hello world is roughly 60–100 MB depending on platform, and the code is still JIT-executed. Perry compiles TypeScript ahead of time to machine code via LLVM: no embedded engine, ~330 KB hello world, ~1 ms startup. See the full Perry vs Bun and Perry vs Deno comparisons.
How is Perry different from Electron or Tauri?
Electron ships Chromium and Node.js with every app, so installers start at roughly 80–150 MB. Tauri is much smaller but still renders a web frontend in the system webview, with app logic in Rust. Perry uses no webview at all: TypeScript compiles to machine code that drives real platform widgets — AppKit, UIKit, GTK4, Win32 — in a single process. See the full Perry vs Electron and Perry vs Tauri comparisons.
How mature is Perry?
Perry is pre-1.0 and moving fast, but real apps built with it are shipping today — Bloom Engine, Mango, Hone, Pry, and dB Meter among them. See the showcase for details.
More questions? Read the getting-started guide or ask on GitHub Discussions.