[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-74662":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":25,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":31,"readmeContent":32,"aiSummary":33,"trendingCount":16,"starSnapshotCount":16,"syncStatus":34,"lastSyncTime":35,"discoverSource":36},74662,"perry","PerryTS\u002Fperry","PerryTS","A native TypeScript compiler written in Rust. Compiles TypeScript directly to executables using SWC and LLVM.","https:\u002F\u002Fwww.perryts.com",null,"Rust",3730,125,8,58,0,109,189,941,327,28.3,"MIT License",false,"main",true,[27,28,29,30],"compile","cranelift","smc","typescript","2026-06-12 02:03:26","# Perry\n\n**One codebase. Every platform. Native performance.**\n\nPerry is a native TypeScript compiler written in Rust. It takes your TypeScript and compiles it straight to native executables — no Node.js, no Electron, no browser engine. Just fast, small binaries that run anywhere.\n\n**Current Version:** 0.5.152 | [Website](https:\u002F\u002Fperryts.com) | [Documentation](https:\u002F\u002Fperryts.github.io\u002Fperry\u002F) | [Showcase](https:\u002F\u002Fperryts.com\u002Fshowcase)\n\n```bash\nperry compile src\u002Fmain.ts -o myapp\n.\u002Fmyapp    # that's it — a standalone native binary\n```\n\nPerry uses [SWC](https:\u002F\u002Fswc.rs\u002F) for TypeScript parsing and [LLVM](https:\u002F\u002Fllvm.org\u002F) for native code generation. The output is a single binary with no runtime dependencies.\n\n---\n\n## Built with Perry\n\nPeople are building real apps with Perry today. Here are some highlights:\n\n| Project | What it is | Platforms |\n|---------|-----------|-----------|\n| [**Bloom Engine**](https:\u002F\u002Fbloomengine.dev) | Native TypeScript game engine — Metal, DirectX 12, Vulkan, OpenGL. Write games in TS, ship native. | macOS, Windows, Linux, iOS, tvOS, Android |\n| [**Mango**](https:\u002F\u002Fgithub.com\u002FMangoQuery\u002Fapp) | Native MongoDB GUI. ~7 MB binary, \u003C100 MB RAM, sub-second cold start. | macOS, Windows, Linux, iOS, Android |\n| [**Hone**](https:\u002F\u002Fhone.codes) | AI-powered native code editor with built-in terminal, Git, and LSP. | macOS, Windows, Linux, iOS, Android, Web |\n| [**Pry**](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fpry) | Fast, native JSON viewer with tree navigation and search. | macOS, iOS, Android |\n| [**dB Meter**](https:\u002F\u002Fdbmeter.app) | Real-time sound level measurement with 60fps updates and per-device calibration. | iOS, macOS, Android |\n\n### Screenshots\n\n**Mango** — Native MongoDB GUI ([source](https:\u002F\u002Fgithub.com\u002FMangoQuery\u002Fapp))\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fimages\u002Fshowcase\u002Fmango-explorer.png\" width=\"720\" alt=\"Mango — database explorer view\" \u002F>\n\u003C\u002Fp>\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fimages\u002Fshowcase\u002Fmango-editor.png\" width=\"720\" alt=\"Mango — document editor view\" \u002F>\n\u003C\u002Fp>\n\n**Hone** — AI-powered native code editor ([hone.codes](https:\u002F\u002Fhone.codes))\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Fhone.codes\u002Fscreenshot.png\" width=\"720\" alt=\"Hone — AI code editor built with Perry\" \u002F>\n\u003C\u002Fp>\n\n> Have something you've built with Perry? Open a PR to add it here!\n\n---\n\n## Performance\n\n> **As of v0.5.585, fast-math is opt-in.** Perry's default mode emits no `reassoc + contract` per-instruction FMF flags, so f64 arithmetic is bit-exact with Node. `--fast-math` (CLI), `PERRY_FAST_MATH=1` (env), or `\"perry\": { \"fastMath\": true }` in `package.json` re-enables the flags. See [`docs\u002Fsrc\u002Fcli\u002Ffast-math.md`](docs\u002Fsrc\u002Fcli\u002Ffast-math.md) for the discussion of when it does and doesn't matter. The numbers below are Perry's default mode unless noted.\n\nNumbers below are from a 2026-05-14 sweep on macOS ARM64 (M1 Max, RUNS=11 medians, `taskpolicy -t 0 -l 0`) at Perry v0.5.908 on an otherwise-idle machine. All languages re-measured together this run. Source + methodology in [`benchmarks\u002Fpolyglot\u002F`](benchmarks\u002Fpolyglot\u002F).\n\n| Benchmark           | Perry |  Rust |   C++ |    Go | Swift |  Java |  Node |   Bun | What it tests |\n|---------------------|------:|------:|------:|------:|------:|------:|------:|------:|---------------|\n| fibonacci           |   309 |   316 |   309 |   446 |   401 |   278 |   987 |   518 | Recursive function calls (i64 specialization) |\n| loop_data_dependent |   225 |   226 |   129 |   128 |   225 |   226 |   226 |   230 | Multiplicative carry through `sum` (genuinely-non-foldable f64) |\n| object_create       |     2 |     0 |     0 |     0 |     0 |     5 |     8 |     6 | Object allocation (1M objects, scalar replacement) |\n| nested_loops        |    18 |     8 |     8 |    10 |     8 |    10 |    17 |    20 | Nested array access (cache-bound) |\n| array_read          |    11 |     9 |     9 |    10 |     9 |    11 |    14 |    16 | Sequential read (10M elements) |\n| array_write         |     3 |     7 |     2 |     9 |     2 |     6 |     9 |     6 | Sequential write (10M elements) |\n\nDefault Perry runs in the same neighborhood as Rust default `-O`, C++ `-O3`, and Swift `-O` on every row — competitive on integer recursion (`fibonacci` 309 vs Rust 316 \u002F C++ 309), within a tick of native on object allocation thanks to scalar replacement (`object_create`), within a few ms on cache-bound work (`nested_loops`, `array_read`\u002F`array_write`), and matching the no-contract compiled pack on genuinely-non-foldable f64 (`loop_data_dependent` 225 vs Rust 226 \u002F Bun 230 \u002F Node 226). Apple Clang `-O3` and Go default win the `loop_data_dependent` row at 128-129 by fusing `sum * a + b` into a single `FMADDD` instruction (FMA contraction is `-ffp-contract=fast` — a separate knob `--fast-math` deliberately doesn't toggle). Python column omitted to keep the table readable; full numbers in [`benchmarks\u002Fpolyglot\u002FRESULTS.md`](benchmarks\u002Fpolyglot\u002FRESULTS.md).\n\nWe deliberately don't lead with the trivially-foldable accumulator microbenchmarks (`loop_overhead` \u002F `math_intensive` \u002F `accumulate`) that Perry posted big numbers on through v0.5.584. Those are flag-aggressiveness probes — they measure whether each compiler applied `reassoc + autovectorize` to a `sum += 1.0`-shaped loop, not how fast the resulting loop computes under load. Perry default sits in the no-flags pack (97 \u002F 51 \u002F 97 ms in this sweep) on all three; `--fast-math` recovers 12 \u002F 14 \u002F 34 ms. C++ `-O3 -ffast-math` matches Perry `--fast-math` to the millisecond on the same kernels — same LLVM pipeline, one flag. The full breakdown is in [`benchmarks\u002FREADME.md`](benchmarks\u002FREADME.md#optimization-probes-compiler-flag-aggressiveness-not-runtime-perf) and [`polyglot\u002FRESULTS_OPT.md`](benchmarks\u002Fpolyglot\u002FRESULTS_OPT.md).\n\n### vs Node.js and Bun\n\nPerry's broader benchmark suite covers workloads outside the polyglot set — closures, classes, JSON, prime sieve, etc. Numbers below from the 2026-05-14 v0.5.908 sweep via `benchmarks\u002Fsuite\u002Frun_benchmarks.sh` (single-run-per-cell, not RUNS=11 medians — see [`benchmarks\u002Fpolyglot\u002F`](benchmarks\u002Fpolyglot\u002F) for the rigorous multi-run methodology).\n\n| Benchmark | Perry (v0.5.908) | Node.js | Bun | What it tests |\n|-----------|-----------------:|--------:|----:|---------------|\n| factorial | 107ms | 591ms | 97ms | Modular accumulation (integer fast path) |\n| method_calls | 9ms | 11ms | 9ms | Class method dispatch (10M calls) |\n| closure | 50ms | 304ms | 51ms | Closure creation + invocation (10M calls) |\n| binary_trees | 2ms | 10ms | 7ms | Tree allocation + traversal (1M nodes, scalar replacement) |\n| string_concat | 0ms | 3ms | 1ms | 100K string appends |\n| prime_sieve | 3ms | 8ms | 7ms | Sieve of Eratosthenes |\n| mandelbrot | 28ms | 25ms | 29ms | Complex f64 iteration (800x800) |\n| matrix_multiply | 28ms | 34ms | 34ms | 256x256 matrix multiply |\n| json_roundtrip (lazy tape, gen-gc) | 83ms | 377ms | 249ms | 50× `JSON.parse` + `JSON.stringify` on a ~1MB, 10K-item blob |\n\n`closure` and `factorial` are still slower than the older v0.5.173 baseline (10 → 50 ms, 31 → 107 ms). The v0.5.585 fast-math opt-in flip accounts for `factorial` (integer modulo plus an FP-tail reduction that the old default-on fast-math collapsed); `closure` regression is tracked as a follow-up. `method_calls` is back at baseline this sweep (9 ms) — yesterday's 25 ms reading was single-run noise from concurrent CPU load. The wins on `binary_trees` \u002F `string_concat` \u002F `prime_sieve` \u002F `mandelbrot` \u002F `matrix_multiply` against Node\u002FBun hold steady. Single-run cells are noisier than RUNS=11 medians; the lower-noise multi-run polyglot table above remains the canonical comparison.\n\nPerry compiles to native machine code via LLVM — no JIT warmup, no interpreter overhead. Key optimizations that apply in both modes: **scalar replacement** of non-escaping objects (escape analysis eliminates heap allocation entirely — object fields become registers), inline bump allocator for objects that do escape, i32 loop counters for bounded array access, integer-modulo fast path (`fptosi → srem → sitofp` instead of `fmod`), elimination of redundant `js_number_coerce` calls on numeric function returns, and i64 specialization for pure numeric recursive functions.\n\nRun benchmarks yourself: `cd benchmarks\u002Fsuite && .\u002Frun_benchmarks.sh` (requires node, cargo; optional: bun, shermes).\n\n## Binary Size\n\nPerry produces small, self-contained binaries with no external dependencies at run time:\n\n| Program | Binary Size |\n|---------|-------------|\n| `console.log(\"Hello, world!\")` | **~330KB** |\n| hello world + `fs` \u002F `path` \u002F `process` imports | ~380KB |\n| full stdlib app (fastify, mysql2, etc.) | ~48MB |\n| with `--enable-js-runtime` (V8 embedded) | +~15MB |\n\nPerry automatically detects which parts of the runtime your program uses and only links what's needed.\n\n---\n\n## Installation\n\n### npm \u002F npx (any platform)\n\nPerry ships as a prebuilt-binary npm package — the fastest way to try it, and the only install path that works on all seven supported platforms (macOS arm64\u002Fx64, Linux x64\u002Farm64 glibc + musl, Windows x64) with one command:\n\n```bash\n# Project-local (recommended — pins Perry's version alongside your deps)\nnpm install @perryts\u002Fperry\nnpx perry compile src\u002Fmain.ts -o myapp && .\u002Fmyapp\n\n# Global\nnpm install -g @perryts\u002Fperry\nperry compile src\u002Fmain.ts -o myapp\n\n# Zero-install, one-shot\nnpx -y @perryts\u002Fperry compile src\u002Fmain.ts -o myapp\n```\n\n[`@perryts\u002Fperry`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@perryts\u002Fperry) is a thin launcher; npm automatically picks the matching prebuilt via `optionalDependencies` (`@perryts\u002Fperry-darwin-arm64`, `@perryts\u002Fperry-linux-x64-musl`, etc.) based on your `os` \u002F `cpu` \u002F `libc`. Requires Node.js ≥ 16 and a system C toolchain for linking (same as any Perry install — see [Requirements](#requirements)).\n\n### macOS (Homebrew)\n\n```bash\nbrew install perryts\u002Fperry\u002Fperry\n```\n\n### Windows (winget)\n\n```bash\nwinget install PerryTS.Perry\n```\n\n### Windows (Scoop)\n\n```powershell\nscoop bucket add perry-ts https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry\nscoop install perry-ts\u002Fperry\n```\n\nThe Scoop manifest declares `main\u002Fllvm` as a dependency, so `scoop install` automatically pulls the official MSVC-default LLVM toolchain Perry needs for Windows-native object emission. Verify with `perry doctor` after install.\n\n### Debian \u002F Ubuntu (APT)\n\n```bash\ncurl -fsSL https:\u002F\u002Fperryts.github.io\u002Fperry-apt\u002Fperry.gpg.pub | sudo gpg --dearmor -o \u002Fusr\u002Fshare\u002Fkeyrings\u002Fperry.gpg\necho \"deb [signed-by=\u002Fusr\u002Fshare\u002Fkeyrings\u002Fperry.gpg] https:\u002F\u002Fperryts.github.io\u002Fperry-apt stable main\" | sudo tee \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fperry.list\nsudo apt update && sudo apt install perry\n```\n\n### Quick install (macOS \u002F Linux)\n\n```bash\ncurl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002FPerryTS\u002Fperry\u002Fmain\u002Fpackaging\u002Finstall.sh | sh\n```\n\n### From source\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry.git\ncd perry\ncargo build --release\n# Binary at: target\u002Frelease\u002Fperry\n```\n\n### Requirements\n\nPerry requires a C linker to link compiled executables:\n- **macOS:** Xcode Command Line Tools (`xcode-select --install`)\n- **Linux:** GCC or Clang (`sudo apt install build-essential`)\n- **Windows:** MSVC (Visual Studio Build Tools)\n\nRun `perry doctor` to verify your environment.\n\n---\n\n## Quick Start\n\n```bash\n# Initialize a new project\nperry init my-project\ncd my-project\n\n# Compile and run\nperry compile src\u002Fmain.ts -o myapp\n.\u002Fmyapp\n\n# Or compile and run in one step\nperry run .\n\n# Check TypeScript compatibility\nperry check src\u002F\n\n# Diagnose environment\nperry doctor\n```\n\n---\n\n## Real-World Example: API Server with ESM Modules\n\nPerry supports standard ES module imports and npm packages. Here's a real-world API server with multi-file project structure:\n\n**Project layout:**\n```\nmy-api\u002F\n├── package.json\n├── src\u002F\n│   ├── main.ts\n│   ├── config.ts\n│   └── routes\u002F\n│       └── users.ts\n└── node_modules\u002F\n```\n\n**src\u002Fconfig.ts**\n```typescript\nexport const config = {\n  port: 3000,\n  dbHost: process.env.DB_HOST || 'localhost',\n};\n```\n\n**src\u002Froutes\u002Fusers.ts**\n```typescript\nexport function getUsers(): object[] {\n  return [\n    { id: 1, name: 'Alice' },\n    { id: 2, name: 'Bob' },\n  ];\n}\n\nexport function getUserById(id: number): object | undefined {\n  return getUsers().find((u: any) => u.id === id);\n}\n```\n\n**src\u002Fmain.ts**\n```typescript\nimport fastify from 'fastify';\nimport { config } from '.\u002Fconfig';\nimport { getUsers, getUserById } from '.\u002Froutes\u002Fusers';\n\nconst app = fastify();\n\napp.get('\u002Fapi\u002Fusers', async () => {\n  return getUsers();\n});\n\napp.get('\u002Fapi\u002Fusers\u002F:id', async (request) => {\n  const { id } = request.params as { id: string };\n  return getUserById(parseInt(id));\n});\n\napp.listen({ port: config.port }, () => {\n  console.log(`Server running on port ${config.port}`);\n});\n```\n\n**Compile and run:**\n```bash\nperry compile src\u002Fmain.ts -o my-api && .\u002Fmy-api\n# or: perry run .\n```\n\nThe output is a standalone binary — no `node_modules` needed at runtime.\n\n---\n\n## Example Projects\n\nReady-to-run demos live in their own repo: **[PerryTS\u002Fperry-examples](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples)**.\n\n| Example | Stack | What it demonstrates |\n|---------|-------|---------------------|\n| **[express-postgres](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Fexpress-postgres)** | Express + PostgreSQL | Multi-file routes, middleware (CORS, Helmet), connection pooling, error handling |\n| **[fastify-redis-mysql](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Ffastify-redis-mysql)** | Fastify + Redis + MySQL | Rate limiting, caching layer, database queries, dotenv config |\n| **[hono-mongodb](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Fhono-mongodb)** | Hono + MongoDB | Lightweight HTTP framework with document database |\n| **[nestjs-typeorm](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Fnestjs-typeorm)** | NestJS + TypeORM | Decorator-based architecture, dependency injection |\n| **[nextjs-prisma](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Fnextjs-prisma)** | Next.js-style + Prisma | ORM integration, database migrations |\n| **[koa-redis](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Fkoa-redis)** | Koa + Redis | Middleware composition, session storage |\n| **[blockchain-demo](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\u002Ftree\u002Fmain\u002Fblockchain-demo)** | Custom | Blockchain implementation in pure TypeScript |\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry-examples\ncd perry-examples\u002Ffastify-redis-mysql\nnpm install\nperry compile src\u002Findex.ts -o server && .\u002Fserver\n```\n\n---\n\n## Native UI\n\nPerry includes a declarative UI system (`perry\u002Fui`) that compiles directly to native platform widgets — no WebView, no Electron. The programming model is SwiftUI-like: compose native widgets with stack-based layout, alignment, and distribution — not CSS\u002FHTML.\n\n```typescript\nimport {\n  App, VStack, HStack, Text, Button, Spacer, SplitView, splitViewAddChild,\n  stackSetAlignment, stackSetDistribution, widgetAddChild, widgetMatchParentWidth,\n} from 'perry\u002Fui';\n\n\u002F\u002F Sidebar + content layout with a split view\nconst sidebar = VStack(8, [Text(\"Projects\"), Text(\"Settings\"), Spacer()]);\nsidebar.setEdgeInsets(12, 12, 12, 12);\nsidebar.setBackgroundColor(\"#F5F5F5\");\n\nconst header = HStack(8, [Text(\"Dashboard\"), Spacer(), Button(\"New\", () => {})]);\nconst actions = HStack(8, [Button(\"Cancel\", () => {}), Button(\"Save\", () => {})]);\nstackSetDistribution(actions, 1); \u002F\u002F FillEqually — both buttons get equal width\n\nconst content = VStack(16, [header, Text(\"Welcome back!\"), Spacer(), actions]);\ncontent.setEdgeInsets(20, 20, 20, 20);\nstackSetAlignment(content, 5); \u002F\u002F Leading — children align left\n\nconst split = SplitView();\nsplitViewAddChild(split, sidebar);\nsplitViewAddChild(split, content);\n\nApp({ title: 'My App', width: 800, height: 500, body: split });\n```\n\n**10 target outputs from one codebase:**\n\n| Platform | Backend | Target Flag |\n|----------|---------|-------------|\n| macOS | AppKit (NSView) | *(default on macOS)* |\n| iOS \u002F iPadOS | UIKit | `--target ios` \u002F `--target ios-simulator` |\n| visionOS | UIKit (2D windows) | `--target visionos` \u002F `--target visionos-simulator` |\n| tvOS | UIKit | `--target tvos` \u002F `--target tvos-simulator` |\n| watchOS | WatchKit | `--target watchos` \u002F `--target watchos-simulator` |\n| Android | Android Views (JNI) | `--target android` |\n| Windows | Win32 | *(default on Windows)* |\n| Linux | GTK4 | *(default on Linux)* |\n| Web | DOM (JS codegen) | `--target web` |\n| WebAssembly | DOM (WASM) | `--target wasm` |\n\n**127+ UI functions** — widgets (Button, Text, TextField, Toggle, Slider, Picker, Table, Canvas, Image, ProgressView, SecureField, NavigationStack, ZStack, LazyVStack, Form\u002FSection, CameraView, SplitView), layout control (alignment, distribution, match-parent, content hugging, overlay positioning, edge insets), and system APIs (keychain, notifications, file dialogs, clipboard, dark mode, openURL, audio capture).\n\n---\n\n## Multi-Threading\n\nThe `perry\u002Fthread` module provides real OS threads with compile-time safety — no shared mutable state, no data races:\n\n```typescript\nimport { parallelMap, parallelFilter, spawn } from 'perry\u002Fthread';\n\n\u002F\u002F Data-parallel array processing across all CPU cores\nconst results = parallelMap([1, 2, 3, 4, 5], n => fibonacci(n));\n\n\u002F\u002F Parallel filtering\nconst evens = parallelFilter(numbers, n => n % 2 === 0);\n\n\u002F\u002F Background thread with Promise\nconst result = await spawn(() => expensiveComputation());\n```\n\nValues cross threads via deep-copy. Each thread gets its own arena and GC. The compiler enforces that closures don't capture mutable state.\n\n---\n\n## Internationalization (i18n)\n\nCompile-time localization with zero runtime overhead:\n\n```typescript\nimport { t, Currency, ShortDate } from 'perry\u002Fi18n';\n\nconsole.log(t('hello'));                    \u002F\u002F \"Hallo\" (German locale)\nconsole.log(t('items', { count: 3 }));     \u002F\u002F \"3 Artikel\" (CLDR plural rules)\nconsole.log(Currency(9.99, 'EUR'));         \u002F\u002F \"9,99 €\"\nconsole.log(ShortDate(Date.now()));        \u002F\u002F \"24.03.2026\"\n```\n\nConfigure in `perry.toml`:\n\n```toml\n[i18n]\ndefault_locale = \"en\"\nlocales = [\"en\", \"de\", \"fr\", \"ja\"]\n```\n\nAll locale strings are baked into the binary at compile time. Native locale detection on all 6 platforms. CLDR plural rules for 30+ locales.\n\n---\n\n## Home Screen Widgets (WidgetKit)\n\nBuild native home screen widgets from TypeScript — iOS, Android, watchOS, and Wear OS:\n\n```bash\nperry compile src\u002Fwidget.ts --target ios-widget -o MyWidget\nperry compile src\u002Fwidget.ts --target android-widget -o MyWidget\nperry compile src\u002Fwidget.ts --target watchos-widget -o MyWidget\nperry compile src\u002Fwidget.ts --target wearos-tile -o MyWidget\n```\n\n---\n\n## Cross-Platform Targets\n\n```bash\n# Desktop (default for host platform)\nperry compile src\u002Fmain.ts -o myapp\n\n# Mobile\nperry compile src\u002Fmain.ts --target ios -o MyApp\nperry compile src\u002Fmain.ts --target ios-simulator -o MyApp\nperry compile src\u002Fmain.ts --target visionos -o MyApp\nperry compile src\u002Fmain.ts --target visionos-simulator -o MyApp\nperry compile src\u002Fmain.ts --target android -o MyApp\n\n# TV \u002F Watch\nperry compile src\u002Fmain.ts --target tvos -o MyApp\nperry compile src\u002Fmain.ts --target watchos -o MyApp\n\n# Web\nperry compile src\u002Fmain.ts --target web -o app.html       # JavaScript output\nperry compile src\u002Fmain.ts --target wasm -o app.wasm      # WebAssembly output\n\n# Home screen widgets\nperry compile src\u002Fwidget.ts --target ios-widget -o MyWidget\nperry compile src\u002Fwidget.ts --target android-widget -o MyWidget\nperry compile src\u002Fwidget.ts --target wearos-tile -o MyWidget\n```\n\n---\n\n## Publishing\n\n```bash\nperry publish macos   # or: ios \u002F android \u002F linux\n```\n\n`perry publish` sends your TypeScript source to perry-hub (the cloud build server), which cross-compiles and signs for each target platform.\n\n---\n\n## Supported Language Features\n\n### Core TypeScript\n\n| Feature | Status |\n|---------|--------|\n| Variables (let, const, var) | ✅ |\n| All operators (+, -, *, \u002F, %, **, &, \\|, ^, \u003C\u003C, >>, ???, ?., ternary) | ✅ |\n| Control flow (if\u002Felse, for, while, switch, break, continue) | ✅ |\n| Try-catch-finally, throw | ✅ |\n| Functions, arrow functions, rest params, defaults | ✅ |\n| Closures with mutable captures | ✅ |\n| Classes (inheritance, private fields #, static, getters\u002Fsetters, super) | ✅ |\n| Generics (monomorphized at compile time) | ✅ |\n| Interfaces, type aliases, union types, type guards | ✅ |\n| Async\u002Fawait, Promise | ✅ |\n| Generators (function*) | ✅ |\n| ES modules (import\u002Fexport, re-exports, `import * as`) | ✅ |\n| Destructuring (array, object, rest, defaults, rename) | ✅ |\n| Spread operator in calls and literals | ✅ |\n| RegExp (test, match, replace) | ✅ |\n| BigInt (256-bit) | ✅ |\n| Decorators | ❌ ([not supported](docs\u002Fsrc\u002Flanguage\u002Flimitations.md#no-decorators)) |\n\n### Standard Library\n\n| Module | Functions |\n|--------|-----------|\n| `console` | log, error, warn, debug |\n| `fs` | readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, readdirSync, statSync, readFileBuffer, rmRecursive |\n| `path` | join, dirname, basename, extname, resolve |\n| `process` | env, exit, cwd, argv, uptime, memoryUsage |\n| `JSON` | parse, stringify |\n| `Math` | floor, ceil, round, abs, sqrt, pow, min, max, random, log, sin, cos, tan, PI |\n| `Date` | Date.now(), new Date(), toISOString(), component getters |\n| `crypto` | randomBytes, randomUUID, sha256, md5 |\n| `os` | platform, arch, hostname, homedir, tmpdir, totalmem, freemem, uptime, type, release |\n| `Buffer` | from, alloc, allocUnsafe, byteLength, isBuffer, concat; instance methods |\n| `child_process` | execSync, spawnSync, spawnBackground, getProcessStatus, killProcess |\n| `Map` | get, set, has, delete, size, clear, forEach, keys, values, entries |\n| `Set` | add, has, delete, size, clear, forEach |\n| `setTimeout\u002FclearTimeout` | ✅ |\n| `setInterval\u002FclearInterval` | ✅ |\n| `worker_threads` | parentPort, workerData |\n\n### Native npm Package Implementations\n\nThese packages are natively implemented in Rust — no Node.js required:\n\n| Category | Packages |\n|----------|----------|\n| **HTTP** | fastify, axios, node-fetch, ws (WebSocket) |\n| **Database** | mysql2, pg, ioredis |\n| **Security** | bcrypt, argon2, jsonwebtoken |\n| **Utilities** | dotenv, uuid, nodemailer, zlib, node-cron |\n\n---\n\n## Compiling npm Packages Natively\n\nPerry can compile pure TypeScript\u002FJavaScript npm packages directly to native code instead of routing them through the V8 runtime. Add a `perry.compilePackages` array to your `package.json`:\n\n```json\n{\n  \"perry\": {\n    \"compilePackages\": [\n      \"@noble\u002Fcurves\",\n      \"@noble\u002Fhashes\",\n      \"superstruct\"\n    ]\n  }\n}\n```\n\nThen compile with `--enable-js-runtime` as usual. Packages in the list are compiled natively; all others use the V8 runtime.\n\n**Good candidates:** Pure math\u002Fcrypto libraries, serialization\u002Fencoding, data structures with no I\u002FO.\n**Keep as V8-interpreted:** Packages using HTTP\u002FWebSocket, native addons, or unsupported Node.js builtins.\n\n---\n\n## Compiler Optimizations\n\n- **Scalar Replacement** — escape analysis identifies non-escaping objects (`let p = new Point(x, y); sum += p.x + p.y`); fields are decomposed into stack allocas that LLVM promotes to registers — zero heap allocation\n- **NaN-Boxing** — all values are 64-bit words (f64\u002Fu64); no boxing overhead for numbers\n- **Generational Mark-Sweep GC** — per-thread nursery + old-gen arenas, precise shadow stack + conservative stack scan, two-bit aging, 8-byte GcHeader per alloc\n- **Inline Bump Allocator** — objects that do escape use a 13-cycle inline arena bump (no function call on hot path)\n- **Parallel Compilation** — rayon-based module codegen, transform passes, and symbol scanning across CPU cores\n- **FMA \u002F CSE \u002F Loop Unrolling** — fused multiply-add, common subexpression elimination, 8x loop unroll\n- **Fast-Math Flags** — `reassoc contract` on all f64 ops enables LLVM to break serial accumulator chains into parallel accumulators + NEON vectorization\n- **Integer-Modulo Fast Path** — `fptosi → srem → sitofp` instead of `fmod` for provably-integer locals (64x speedup on factorial)\n- **i64 Specialization** — pure numeric recursive functions compile to native `i64` registers (no f64 round-trips)\n- **i32 Loop Counters** — integer registers for loop variables (no f64 round-trips)\n- **LICM** — loop-invariant code motion for nested loops\n- **Shape-Cached Objects** — 5-6x faster object allocation for escaping objects\n- **TimSort** — O(n log n) hybrid sort for `Array.sort()`\n- **`__platform__` Constant** — compile-time platform elimination (dead code removal per target)\n\n---\n\n## Plugin System\n\nCompile TypeScript as a native shared library plugin:\n\n```bash\nperry compile my-plugin.ts --output-type dylib -o my-plugin.dylib\n```\n\n```typescript\nimport { PluginRegistry } from 'perry\u002Fplugin';\n\nexport function activate(api: any) {\n  api.registerTool('my-tool', (args: any) => { \u002F* ... *\u002F });\n  api.on('event', (data: any) => { \u002F* ... *\u002F });\n}\n```\n\n---\n\n## Testing (Geisterhand)\n\nPerry includes Geisterhand, an in-process UI testing framework with HTTP-driven interaction and screenshot capture:\n\n```bash\nperry compile src\u002Fmain.ts --enable-geisterhand -o myapp\n.\u002Fmyapp\n# UI test server runs on http:\u002F\u002Flocalhost:7676\n```\n\nSupports screenshot capture on all native platforms. See the [Geisterhand docs](https:\u002F\u002Fperryts.github.io\u002Fperry\u002Ftesting\u002Fgeisterhand.html) for details.\n\n---\n\n## Ecosystem\n\n| Package | Description |\n|---------|-------------|\n| [**Bloom Engine**](https:\u002F\u002Fbloomengine.dev) | Native TypeScript game engine — 2D\u002F3D rendering, skeletal animation, spatial audio, physics. Metal\u002FDirectX 12\u002FVulkan\u002FOpenGL. |\n| [perry-react](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Freact) | React\u002FJSX that compiles to native widgets. Standard React components → native macOS\u002FiOS\u002FAndroid app. |\n| [perry-sqlite](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fsqlite) | SQLite with a Prisma-compatible API (`findMany`, `create`, `upsert`, `$transaction`, etc.) |\n| [perry-postgres](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fpostgres) | PostgreSQL with the same Prisma-compatible API |\n| [perry-prisma](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fprisma) | MySQL with the same Prisma-compatible API |\n| [perry-apn](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fpush) | Apple Push Notifications (APNs) native library |\n| [@perryts\u002Fthreads](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fperry\u002Ftree\u002Fmain\u002Fpackages\u002Fperry-threads) | Web Worker parallelism (`parallelMap`, `parallelFilter`, `spawn`) for browser\u002FNode.js |\n| [perry-starter](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Fstarter) | Minimal starter project — get up and running in 30 seconds |\n| [perry-demo](https:\u002F\u002Fdemo.perryts.com) | Live benchmark dashboard comparing Perry vs Node.js vs Bun |\n| [perry-react-dom](https:\u002F\u002Fgithub.com\u002FPerryTS\u002Freact-dom) | Perry React DOM bridge |\n\n### perry-react\n\nWrite React components that compile to native widgets — no DOM, no browser:\n\n```tsx\nimport { useState } from 'react';\nimport { createRoot } from 'react-dom\u002Fclient';\n\nfunction Counter() {\n  const [n, setN] = useState(0);\n  return (\n    \u003Cdiv>\n      \u003Ch1>Count: {n}\u003C\u002Fh1>\n      \u003Cbutton onClick={() => setN(n + 1)}>+\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n\ncreateRoot(null, { title: 'Counter', width: 300, height: 200 }).render(\u003CCounter \u002F>);\n```\n\n### perry-sqlite \u002F perry-postgres \u002F perry-prisma\n\nDrop-in replacements for `@prisma\u002Fclient` backed by Rust (sqlx):\n\n```typescript\nimport { PrismaClient } from 'perry-sqlite';\n\nconst prisma = new PrismaClient();\nawait prisma.$connect();\n\nconst users = await prisma.user.findMany({\n  where: { email: { contains: '@example.com' } },\n  orderBy: { createdAt: 'desc' },\n  take: 20,\n});\n\nawait prisma.$disconnect();\n```\n\n---\n\n## Commands\n\n| Command | What it does |\n|---------|-------------|\n| `perry compile \u003Cinput.ts> -o \u003Coutput>` | Compile TypeScript to a native binary |\n| `perry run \u003Cpath> [platform]` | Compile and run in one step (supports `ios`, `android`, etc.) |\n| `perry init \u003Cname>` | Scaffold a new project |\n| `perry check \u003Cpath>` | Validate TypeScript compatibility without compiling |\n| `perry publish \u003Cplatform>` | Build, sign, and publish via the cloud build server |\n| `perry doctor` | Check your development environment |\n| `perry i18n extract` | Extract translatable strings from source |\n\n### Compiler flags\n\n```\n-o, --output \u003Cname>      Output file name\n--target \u003Ctarget>        ios | ios-simulator | visionos | visionos-simulator |\n                         tvos | tvos-simulator | watchos | watchos-simulator | android |\n                         web | wasm | ios-widget | android-widget |\n                         wearos-tile | watchos-widget\n--output-type \u003Ctype>     executable | dylib\n--enable-js-runtime      Embed V8 for npm package compatibility (+~15MB)\n--enable-geisterhand     Enable UI testing server\n--print-hir              Print HIR for debugging\n```\n\n---\n\n## Project Structure\n\n```\nperry\u002F\n├── crates\u002F\n│   ├── perry\u002F                  # CLI (compile, run, check, init, doctor, publish)\n│   ├── perry-parser\u002F           # SWC TypeScript parser\n│   ├── perry-types\u002F            # Type system\n│   ├── perry-hir\u002F              # HIR data structures and AST→HIR lowering\n│   ├── perry-transform\u002F        # IR passes (closure conversion, async, inlining)\n│   ├── perry-codegen\u002F          # LLVM native codegen\n│   ├── perry-codegen-js\u002F       # JavaScript codegen (--target web)\n│   ├── perry-codegen-wasm\u002F     # WebAssembly codegen (--target wasm)\n│   ├── perry-codegen-swiftui\u002F  # SwiftUI codegen (iOS\u002FwatchOS widgets)\n│   ├── perry-codegen-glance\u002F   # Android Glance widget codegen\n│   ├── perry-codegen-wear-tiles\u002F # Wear OS Tiles codegen\n│   ├── perry-runtime\u002F          # Runtime (NaN-boxing, GC, arena, strings)\n│   ├── perry-stdlib\u002F           # Node.js API support (fastify, mysql2, redis, etc.)\n│   ├── perry-ui-*\u002F             # Native UI (macOS, iOS, tvOS, watchOS, Android, GTK4, Windows)\n│   ├── perry-ui-geisterhand\u002F   # UI testing framework\n│   ├── perry-jsruntime\u002F        # Optional V8 interop via QuickJS\n│   └── perry-diagnostics\u002F      # Error reporting\n├── docs\u002F                       # Documentation site (mdBook)\n├── benchmarks\u002F                 # Benchmark suite (Perry vs Node.js vs Bun)\n├── packages\u002F                   # npm packages (@perryts\u002Fthreads)\n└── test-files\u002F                 # Test suite\n```\n\n---\n\n## Runtime Characteristics\n\n- **Garbage Collection** — generational mark-sweep GC, per-thread nursery + old-gen arenas, precise shadow stack + conservative stack scan, two-bit aging tenures objects after 2 minor cycles, 8-byte GcHeader per allocation\n- **Single-Threaded by Default** — async I\u002FO on Tokio workers, callbacks on main thread. Use `perry\u002Fthread` for explicit multi-threading.\n- **No Runtime Type Checking** — types erased at compile time. Use `typeof` and `instanceof` for runtime checks.\n- **Small Binaries** — ~330KB hello world, ~48MB with full stdlib. Automatically stripped.\n\n---\n\n## Development\n\n```bash\ncargo build --release                                    # Build everything\ncargo build --release -p perry-runtime -p perry-stdlib   # Rebuild runtime (after changes)\ncargo test --workspace --exclude perry-ui-ios            # Run tests\ncargo run --release -- compile file.ts -o out && .\u002Fout   # Compile and run\ncargo run --release -- compile file.ts --print-hir       # Debug HIR\n```\n\n### Adding a new feature\n\n1. **HIR** — add node type to `crates\u002Fperry-hir\u002Fsrc\u002Fir.rs`\n2. **Lowering** — handle AST→HIR in `crates\u002Fperry-hir\u002Fsrc\u002Flower.rs`\n3. **Codegen** — generate LLVM IR in `crates\u002Fperry-codegen\u002Fsrc\u002Fcodegen.rs`\n4. **Runtime** — add runtime functions in `crates\u002Fperry-runtime\u002F` if needed\n5. **Test** — add `test-files\u002Ftest_feature.ts`\n\n---\n\n## Releasing Perry\n\nRelease cadence: patch releases (`0.5.118 → 0.5.119`) ship weekly-ish behind the\nmacOS CI gate. **Major releases** — any bump of the major or minor number\n(e.g. `0.5.x → 0.6.0`, and the upcoming `1.0.0`) — **must be verified on every\nsupported platform** before the tag is pushed. Patch releases only require the\ndefault CI gate.\n\n### 1. Pre-release checklist (every release)\n\nRun on macOS (the canonical dev host):\n\n```bash\n# Full rebuild — runtime\u002Fstdlib\u002FUI libs must match the compiler version.\ncargo build --release\n\n# Core gates.\ncargo test --workspace --exclude perry-ui-ios --exclude perry-ui-tvos \\\n  --exclude perry-ui-watchos --exclude perry-ui-gtk4 \\\n  --exclude perry-ui-android --exclude perry-ui-windows\n.\u002Frun_parity_tests.sh                       # Perry vs node stdout parity\n.\u002Fscripts\u002Frun_doc_tests.sh                  # Compile + run every docs\u002Fexamples\u002F*.ts\n```\n\nThen bump and tag:\n\n```bash\n# Edit Cargo.toml workspace.package.version + CLAUDE.md \"Current Version\".\n# Add a \"Recent Changes\" entry in CLAUDE.md.\ngit commit -am \"release: v0.x.y\"\ngit tag v0.x.y && git push --tags\n```\n\nThe `release-packages.yml` workflow fires on the pushed tag and builds the\ncross-platform matrix (see §3).\n\n### 2. Major-release verification (all platforms)\n\nBefore tagging a major\u002Fminor bump, these must all pass:\n\n| Platform | What to run | Runs in CI? |\n|---|---|---|\n| **macOS** (arm64 + x86_64) | `cargo test` + `run_parity_tests.sh` + `scripts\u002Frun_doc_tests.sh` | Yes, `test.yml` (arm64 only) |\n| **Linux glibc** (x86_64 + aarch64) | Same, under `xvfb-run -a` for UI; `apt install libgtk-4-dev libadwaita-1-dev xvfb` first | Partial — release build only |\n| **Linux musl** (x86_64 + aarch64) | Release build via `release-packages.yml`; spot-check a compiled `hello.ts` runs on Alpine | Build only |\n| **Windows** (x86_64 MSVC) | `scripts\u002Frun_doc_tests.ps1`; smoke-test `perry compile hello.ts -o hello.exe && .\\hello.exe` | Build only |\n| **iOS Simulator** | `perry compile --target ios-simulator examples\u002Fwidget_demo.ts && xcrun simctl install booted out.app` | No (Xcode required) |\n| **visionOS Simulator** | `perry compile --target visionos-simulator ...`, launch in Apple Vision Pro Simulator | No (Xcode required) |\n| **tvOS Simulator** | `perry compile --target tvos-simulator ...`, launch in Simulator | No (Xcode required) |\n| **watchOS Simulator** | `perry compile --target watchos-simulator ...` — requires `rustup toolchain install nightly` + `cargo +nightly -Zbuild-std` | No (Xcode + nightly required) |\n| **Android** | `perry compile --target android examples\u002Fwidget_demo.ts`; install APK on emulator | No (NDK required) |\n| **Web \u002F WASM** | `perry compile --target web examples\u002Fwasm_ui_demo.ts`, open `out.html` in a browser | No |\n| **Home-screen widgets** | `perry compile --target widgetkit ... && perry publish ios` | No |\n\nFor v1.0, expect to spend half a day spinning through the four OS VMs locally.\nLinux + Windows doc-tests are automated in `test.yml`; the mobile\u002Fwatch\u002Fweb\nlanes remain manual pending tier-2 simulator orchestration.\n\n### 2a. Simulator-run recipe (iOS \u002F tvOS)\n\n`perry-ui-ios` and `perry-ui-tvos` honor `PERRY_UI_TEST_MODE=1` — when set,\nthe app renders one frame, optionally writes a screenshot to\n`$PERRY_UI_SCREENSHOT_PATH`, and exits cleanly. Combine with\n`xcrun simctl` to verify a doc-example runs without a human:\n\n```bash\n# Compile for the simulator\nperry compile --target ios-simulator docs\u002Fexamples\u002Fui\u002Fcounter.ts -o counter.app\n\n# Boot a device (one-time; reuse the UDID across runs)\nxcrun simctl boot \"iPhone 15\"\nopen -a Simulator\n\n# Install + launch with test mode\nxcrun simctl install booted counter.app\nPERRY_UI_TEST_MODE=1 \\\n  PERRY_UI_TEST_EXIT_AFTER_MS=500 \\\n  PERRY_UI_SCREENSHOT_PATH=\"$PWD\u002Fcounter-ios.png\" \\\n  xcrun simctl launch --console booted com.example.counter\n\n# App exits 0 after rendering; screenshot lands at counter-ios.png\n```\n\nSame recipe works for `tvos-simulator` + `\"Apple TV\"` device. On watchOS the\nRust Tier-3 toolchain requires `+nightly -Zbuild-std` — see the\n`watchos-simulator` row in the matrix above.\n\n### 3. What CI does on the tag\n\nThe `Release Packages` workflow (`.github\u002Fworkflows\u002Frelease-packages.yml`)\ntriggers on a published GitHub Release or manual `workflow_dispatch`. Matrix\nrunners build:\n\n- `macos-14` \u002F `macos-15` — arm64 + x86_64 Darwin binaries\n- `ubuntu-22.04` \u002F `ubuntu-24.04-arm` — glibc x86_64 + aarch64\n- `ubuntu-22.04` \u002F `ubuntu-24.04-arm` — musl x86_64 + aarch64\n- `windows-latest` — x86_64 MSVC\n\nArtifacts are published to:\n\n1. **npm** (`@perryts\u002Fperry` + seven per-platform optional-deps) — via OIDC\n   Trusted Publisher\n2. **Homebrew** — formula auto-update\n3. **APT** (Debian\u002FUbuntu) — GPG-signed repository\n4. **winget** — manifest auto-update\n5. **hub.perryts.com** — worker notification so cloud build workers refresh\n\nA tag push with a failing platform build aborts the publish step for that\nplatform only; fix-forward with a new patch tag (e.g. `v0.6.1`) rather than\namending the existing one.\n\n### 4. Release gates (what blocks a release)\n\n- Parity tests must clear the threshold in `test-parity\u002Fthreshold.json`\n- `cargo test --workspace` (macOS excluded list as above) must be green\n- `compile-smoke` must compile every file under `test-files\u002F`\n- `doc-tests` must compile + run every example under `docs\u002Fexamples\u002F`\n- Benchmark regressions in `benchmark.yml` hard-fail on release tags (warn only\n  on main-branch pushes)\n\n### 5. If a release goes wrong\n\n- **Wrong artifact published**: tag a new patch release with the fix; npm\n  rejects re-publishes of the same version anyway.\n- **Broken binary on one platform**: the `release-packages.yml` matrix is not\n  `fail-fast: true`, so other platforms still publish. Ship a follow-up patch\n  for the broken one.\n- **CI hook failed after tag**: run `workflow_dispatch` with\n  `publish_npm: true` to retry the npm step.\n\n---\n\n## License\n\nMIT\n","Perry 是一个用 Rust 编写的原生 TypeScript 编译器，能够直接将 TypeScript 代码编译成可执行文件。其核心功能包括使用 SWC 进行 TypeScript 解析和 LLVM 进行本地代码生成，从而产生独立的、无需依赖 Node.js 或浏览器引擎即可运行的二进制文件。Perry 的输出是一个单独的二进制文件，没有任何运行时依赖项，这使得它非常适合于需要高性能和跨平台兼容性的应用场景，如游戏引擎、数据库 GUI 工具或 AI 驱动的代码编辑器等。通过 Perry，开发者可以轻松地将 TypeScript 项目转化为可在多种操作系统上高效运行的应用程序。",2,"2026-06-11 03:50:20","high_star"]