perry README

The project's README from github.com/PerryTS/perry. As one markdown file: README.md.

Perry

Write TypeScript. Ship native. Everywhere.

Perry compiles the TypeScript you already write into real machine-code executables — for macOS, Windows, Linux, iOS, Android, watchOS, and TV. No Node.js to install. No Electron to bundle. No runtime at all. Just a binary. (The same codebase can also target the web, emitted as JavaScript or WebAssembly.)

Latest release Join the Perry Discord community

Website · Documentation · Showcase · Examples

perry compile src/main.ts -o myapp
./myapp    # a standalone native binary — ~330 KB for hello world

The language you know. The deployment you wish it had.

Millions of developers write TypeScript every day — but shipping it has always meant shipping a JavaScript engine: a Node install on every server, ~100 MB of embedded runtime per CLI, or a whole browser engine per desktop app. Perry removes the engine. SWC parses your code, LLVM compiles it to machine code, and you get what systems languages get: instant cold starts, tiny self-contained binaries, real threads — without leaving TypeScript.

Perry Node.js Bun Electron
What you ship One native binary, from ~330 KB Your code + a Node install One binary embedding the JS engine App bundle with a browser engine
Execution Ahead-of-time machine code JIT JIT JIT
Cold start Instant — no engine to boot, no warmup Engine boot + warmup Engine boot + warmup Browser boot
Native UI (no WebView) ✅ AppKit, UIKit, Android Views, Win32, GTK4 — — Chromium
iOS · Android · watchOS · TV ✅ from the same codebase — — —
Multicore Real OS threads, data-race-safe at compile time worker_threads workers processes

Table describes Perry's native targets. --target web / --target wasm emit JavaScript / WebAssembly that runs in the browser rather than as a native binary.

Performance

Ahead-of-time machine code means no engine boot and no JIT warmup — and on measured workloads, real multiples over the JS runtimes. Highlights from our open benchmark harnesses (Apple M1 Max, medians of repeated runs):

Workload Perry Node.js Bun Rust
Image convolution (4K, 5×5 Gaussian) 354 ms 1,207 ms — 3.4× slower 915 ms — 2.6× slower 392 ms
Fibonacci (recursive calls) 309 ms 987 ms — 3.2× slower 518 ms — 1.7× slower 316 ms
JSON pipeline (100 records) 39 ms 144 ms — 3.7× slower 51 ms — 1.3× slower 34 ms
JSON pipeline (500k records, 108 MB) 1,649 ms 1,010 ms — 1.6× faster 647 ms — 2.5× faster 604 ms
Object allocation (1M objects) 2 ms 8 ms — 4× slower 6 ms — 3× slower <1 ms
Array write (10M elements) 3 ms 9 ms — 3× slower 6 ms — 2× slower 7 ms
Peak memory (JSON pipeline) 3.5 MB 36 MB — 10× more 11 MB — 3× more 1.2 MB

Look at the Rust column again: on convolution, fibonacci, and the array-write loop, TypeScript compiled with Perry runs even with — or ahead of — Rust. And Electron isn't in the table because it doesn't compete here: it ships a whole browser engine per app, where a comparable Perry app is a single-digit-MB native binary.

Sources: convolution & JSON from the systems-language report — pinned to 7beb3a50ca, the last revision whose artifact contains these values; the copy at HEAD was regenerated in #7641 on a host where the harness clock was invalid and now reads 0.0 ms in every timing cell (see this PR). Re-pin to main once it is regenerated. Fibonacci, object allocation & array write from the polyglot sweep (Perry default mode, no fast-math).

We publish everything, including the workloads where V8's JIT still beats us — no cherry-picked table can survive an open harness. Run it yourself: ./benchmarks/run_public_baseline.sh (methodology).

The full published suite, generated from the artifact — including the rows we lose

Generated from benchmarks/results/public-node-bun-v1.json at Perry commit 827a92bad5a5. Lower wall-clock median is better; every row includes complete raw samples and passed correctness checks.

Benchmark Perry Node.js Bun Result What it tests
factorial 59 ms 95 ms 61 ms win vs both Modular accumulation
method_calls 6 ms 9 ms 4 ms mixed Class method dispatch
closure 29 ms 30 ms 29 ms mixed Closure creation and invocation
binary_trees 6 ms 5 ms 9 ms mixed Tree allocation and traversal
string_concat 5 ms 37 ms 12 ms win vs both String append loop
prime_sieve 4 ms 4 ms 5 ms mixed Sieve of Eratosthenes
mandelbrot 15 ms 17 ms 16 ms win vs both Complex-number iteration
matrix_multiply 22 ms 24 ms 22 ms mixed Matrix multiplication
json_roundtrip 186 ms 407 ms 189 ms win vs both Parse and stringify ~1 MB JSON

Why developers pick Perry

Get started in 60 seconds

# Install (macOS · Linux · Windows)
npm install -g @perryts/perry     # or: brew install perryts/perry/perry
                                  # or: winget install PerryTS.Perry

# Create and run a project
perry init my-app && cd my-app
perry run .

npm packages and ES modules work as you'd expect:

import fastify from 'fastify';

const app = fastify();
app.get('/api/users', async () => [{ id: 1, name: 'Alice' }]);
app.listen({ port: 3000 }, () => console.log('Listening on :3000'));
perry compile src/main.ts -o api && ./api    # one binary — no node_modules on the server

Same code, other platforms: --target ios, --target android, --target web… full list in the platforms guide. APT, Scoop, install script, and source builds are in the installation guide; run perry doctor to verify your setup.

Built with Perry

Real products, shipping today:

Project What it is Platforms
Bloom Engine Native TypeScript game engine — Metal, DirectX 12, Vulkan, OpenGL macOS, Windows, Linux, iOS, tvOS, Android
Mango Native MongoDB GUI — ~7 MB binary, sub-second cold start macOS, Windows, Linux, iOS, Android
Hone AI-powered native code editor with terminal, Git, and LSP macOS, Windows, Linux, iOS, Android, Web
dB Meter Real-time sound level measurement at 60 fps iOS, macOS, Android

Mango — native MongoDB GUI built with Perry Hone — AI code editor built with Perry

More in the showcase — built something with Perry? Open a PR and add it.

Documentation

Everything else lives in the docs:

Community

Perry is built in the open — come say hi:

Privacy

Telemetry is opt-in: nothing leaves your machine unless you explicitly enable it in ~/.perry/config.toml, and PERRY_NO_TELEMETRY=1 (or CI=true) always wins. What can be sent is anonymous and redacted — never your source, paths, or project names. Inspect it any time with perry doctor, and see exactly what's in the payload in the privacy & telemetry docs.

Sponsors

Perry's development is backed by our sponsors. 🙏

Skelpo — premium sponsor

💎 Skelpo — Premium Sponsor

Want to support Perry and see your logo here? Get in touch via perryts.com.

License

MIT

perry (PerryTS/perry)

Searching Database…

What is this?Perry compiles the TypeScript or JavaScript you already write directly into native machine-code executables for macOS, Windows, Linux, iOS, Android, watchOS and TV, using SWC to parse and LLVM to generate code, so there is no Node.js runtime or Electron bundle to ship.
Is this a library I import into Node, or a standalone compiler toolchain?It is a standalone ahead-of-time compiler and CLI toolchain, not a library you require() into a Node app: it parses your code with SWC and emits native machine code via LLVM, producing a self-contained binary.
How do I install Perry and compile my first program?Install it via APT, Scoop, the install script, or by building from source per the installation guide, then run the compiler on your entry file; `perry doctor` checks that your setup is correct, and `--target ios` / `--target android` / `--target web` switch the output platform.
Do I need Node.js installed to run the compiled binary?No. Compiled Perry programs have no runtime at all — no Node, no Bun, no embedded browser engine — just the executable itself.
Will my existing Node code and npm packages just run under Perry?Most common Node APIs work: about 97% of Node's own test suite passes across 53 node: modules, plus roughly 50 popular npm packages like Fastify, Express, mysql2 and ioredis — but it is not full Node parity, and supported TypeScript syntax has documented limitations.
Which platforms can I actually ship an app to?From one codebase you can target macOS, iOS, iPadOS, visionOS, tvOS, watchOS, Android, Wear OS, Windows, Linux, and Web/WASM, with a SwiftUI-like API compiling to real native widgets on each.
Does Perry send any telemetry or data off my machine?Telemetry is opt-in only: nothing is sent unless you enable it yourself in ~/.perry/config.toml, and any payload that is sent is anonymous and redacted, never your source code or project names.
How small are the resulting binaries?A 'hello world' compiles to about 330 KB, and a real app like the Mango MongoDB GUI ships as roughly 7 MB with sub-second cold start.
How does Perry make multi-core code safe?It exposes parallelMap, parallelFilter and spawn backed by real OS threads, and the compiler rejects shared mutable state so data races fail to compile rather than crash at runtime.
How much faster is Perry than Node.js or Bun?On the published benchmark suite Perry beats both on workloads like string concatenation and JSON round-trips (over 3x faster than Node in some cases), though V8's JIT still wins on a few large-data cases, and the authors publish the full results including losses.
What kinds of apps have people already built with Perry?Showcased projects include Bloom Engine (a native game engine using Metal/DirectX12/Vulkan), Mango (a native MongoDB GUI), Hone (an AI-powered code editor), and dB Meter (a real-time sound level app) — all shipping across multiple native platforms from one codebase.
What are similar projects?CalcKernel, scriptc, Tov, goose, lightcraft, Kof4j, swift, yew
Creator
PerryTS
Size
482 MB
Stars
5K
Age
8mo
Commits · 90 Days