Skip to content

Latest commit

 

History

History
146 lines (102 loc) · 9.88 KB

File metadata and controls

146 lines (102 loc) · 9.88 KB

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
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; 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).

Why developers pick Perry

  • ⚡ Native speed, zero warmup. LLVM-optimized machine code with escape analysis, scalar replacement, and a generational GC — see the numbers above.
  • 📦 Binaries you can actually email. Hello world is ~330 KB. Perry links only the runtime your program uses. A real MongoDB GUI built with Perry ships as a ~7 MB app.
  • 🔌 Your Node code mostly just works. ~97% pass rate on Node's own test suite across 53 node:* modules — real implementations of fs, http/http2, net/tls, crypto, stream, child_process, worker_threads, fetch and the web globals, plus ~50 popular npm packages (Fastify, Express, mysql2, pg, ioredis, ws, bcrypt, jsonwebtoken…). Plain JavaScript compiles too.
  • 🖥️ One UI codebase, 11 targets. A SwiftUI-like API that compiles to real platform widgets — macOS, iOS, iPadOS, visionOS, tvOS, watchOS, Android, Wear OS, Windows, Linux, Web/WASM. Even home-screen widgets.
  • 🧵 All your cores, safely. parallelMap, parallelFilter, and spawn on real OS threads — the compiler rejects shared mutable state, so data races don't compile.
  • 🔋 Batteries included. Databases, WebSockets, containers, i18n, keychain, notifications, auto-update, a TUI framework — natively implemented and statically linked.

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:

  • 💬 Join the Discord — get help, share what you're building, and talk directly to the people building Perry
  • 🐛 Issues — bug reports and feature requests
  • 🚀 Showcase — apps the community is shipping

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