- Rust toolchain (stable): rustup.rs
- System C compiler (
ccon macOS/Linux, MSVC on Windows)
git clone https://github.com/skelpo/perry.git
cd perry
# Build all crates (release mode recommended)
cargo build --releaseThe binary is at target/release/perry.
Perry has three build profiles, each tuned for a different job (#5422):
| Goal | Command | Profile |
|---|---|---|
| Fastest correctness feedback | cargo check -p perry |
— |
| Optimized local development | cargo build --profile perry-dev -p perry |
perry-dev |
| Release-compatible build | cargo build --release |
release |
| Official distribution artifacts | cargo build --profile dist ... |
dist |
perry-devinheritsreleasebut disables the expensive distribution settings (lto = false,codegen-units = 16,opt-level = 1,incremental = true, no strip) so the edit/build loop stays short. Output is attarget/perry-dev/perry.distmirrorsreleaseexactly (ThinLTO,codegen-units = 1,opt-level = 3, strip) and is the explicit, named profile the release workflows use for shipped artifacts. Output is attarget/dist/.
After a --timings build, scripts/cargo_timing_summary.py prints the slowest
units so build-time regressions are visible.
# Runtime only (must rebuild stdlib too!)
cargo build --release -p perry-runtime -p perry-stdlib
# The .a static archives are emitted by separate wrapper crates (#5422), so a
# plain `cargo build` no longer produces them as a side effect. Build them
# explicitly when you need libperry_runtime.a / libperry_stdlib.a (e.g. to link
# compiled programs without the auto-optimize rebuild):
cargo build --release -p perry-runtime-static -p perry-stdlib-static
# Codegen only
cargo build --release -p perry-codegenImportant: When rebuilding
perry-runtime, you must also rebuildperry-stdlibbecauselibperry_stdlib.aembeds perry-runtime as a static dependency.
The default build is the full official CLI. For compiler work you can build a slimmer CLI that omits the publish / mobile / updater / native / audit commands and the non-native codegen backends (#5422):
cargo build -p perry --no-default-features --features dev-clidev-cli keeps compile / run / check / types / cache / dev. Disabled
commands drop out of --help, and disabled --target backends report a clear
"built without the <feature> feature" error. See crates/perry/Cargo.toml for
the full feature list (full-cli, publish-cli, backend-wasm, …).
# All tests (exclude iOS crate on non-iOS host)
cargo test --workspace --exclude perry-ui-ios
# Specific crate
cargo test -p perry-hir
cargo test -p perry-codegen-llvm# Compile a TypeScript file
cargo run --release -- hello.ts -o hello
./hello
# Debug: print HIR
cargo run --release -- hello.ts --print-hir- Make changes to the relevant crate
cargo build --releaseto buildcargo test --workspace --exclude perry-ui-iosto verify- Test with a real TypeScript file:
cargo run --release -- test.ts -o test && ./test
perry/
├── crates/
│ ├── perry/ # CLI driver
│ ├── perry-parser/ # SWC TypeScript parser
│ ├── perry-types/ # Type definitions
│ ├── perry-hir/ # HIR and lowering
│ ├── perry-transform/ # IR passes
│ ├── perry-codegen-llvm/ # LLVM native codegen
│ ├── perry-codegen-wasm/ # WebAssembly codegen (--target web / --target wasm)
│ ├── perry-codegen-js/ # JS minifier (formerly the web target's codegen)
│ ├── perry-codegen-swiftui/ # Widget codegen
│ ├── perry-runtime/ # Runtime library
│ ├── perry-stdlib/ # npm package implementations
│ ├── perry-ui/ # Shared UI types
│ ├── perry-ui-macos/ # macOS AppKit UI
│ ├── perry-ui-ios/ # iOS UIKit UI
│ └── perry-jsruntime/ # QuickJS integration
├── docs/ # This documentation (mdBook)
├── CLAUDE.md # Detailed implementation notes
└── CHANGELOG.md # Version history
- Architecture — Crate map and pipeline overview
- See
CLAUDE.mdfor detailed implementation notes and pitfalls