Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI Commands

Perry provides 11 commands for compiling, checking, running, publishing, and managing your projects.

See also: perry.toml Reference for project configuration.

compile

Compile TypeScript to a native executable.

perry compile main.ts -o app
# Or shorthand (auto-detects compile):
perry main.ts -o app
FlagDescription
-o, --output <PATH>Output file path
--target <TARGET>Platform target (see Compiler Flags)
--output-type <TYPE>executable (default) or dylib (plugin)
--print-hirPrint HIR intermediate representation
--no-linkProduce object file only, skip linking
--keep-intermediatesKeep .o and .asm files
--enable-js-runtimeEnable V8 JavaScript runtime fallback
--type-checkEnable type checking via tsgo
--minifyMinify and obfuscate output (auto-enabled for --target web)
--app-bundle-id <ID>Bundle ID (required for widget targets)
--bundle-extensions <DIR>Bundle TypeScript extensions from directory
# Basic compilation
perry compile app.ts -o app

# Cross-compile for iOS Simulator
perry compile app.ts -o app --target ios-simulator

# Build a plugin
perry compile plugin.ts --output-type dylib -o plugin.dylib

# Debug: view intermediate representation
perry compile app.ts --print-hir

# Build an iOS widget
perry compile widget.ts --target ios-widget --app-bundle-id com.myapp.widget

run

Compile and launch your app in one step.

perry run                          # Auto-detect entry file
perry run ios                      # Run on iOS device/simulator
perry run visionos                 # Run on Apple Vision Pro simulator/device
perry run android                  # Run on Android device
perry run -- --port 3000           # Forward args to your program
Argument / FlagDescription
iosTarget iOS (device or simulator)
visionosTarget visionOS (device or simulator)
macosTarget macOS (default on macOS host)
webTarget web (opens in browser)
androidTarget Android device
--simulator <UDID>Specify iOS simulator by UDID
--device <UDID>Specify iOS physical device by UDID
--localForce local compilation (no remote fallback)
--remoteForce remote build via Perry Hub
--enable-js-runtimeEnable V8 JavaScript runtime
--type-checkEnable type checking via tsgo
--Separator for program arguments

Entry file detection (checked in order):

  1. perry.toml[project] entry field
  2. src/main.ts
  3. main.ts

Device detection: When targeting iOS, Perry auto-discovers available simulators (via simctl) and physical devices (via devicectl). For Android, it uses adb. When multiple targets are found, an interactive prompt lets you choose.

Remote build fallback: If cross-compilation toolchains aren’t installed locally (e.g., Apple mobile targets on a machine without Xcode), perry run ios and perry run visionos can fall back to Perry Hub’s build server when the backend supports the target. Use --local or --remote to force either path.

# Run a CLI program
perry run

# Run on a specific simulator
perry run ios --simulator 12345-ABCDE

# Force remote build
perry run ios --remote

# Run web target
perry run web

dev

Watch your TypeScript source tree and auto-recompile + relaunch on every save.

perry dev src/main.ts                        # watch + rebuild + relaunch on save
perry dev src/server.ts -- --port 3000       # forward args to the child
perry dev src/app.ts --watch shared/         # watch an extra directory
perry dev src/app.ts -o build/dev-app        # override output path
FlagDescription
-o, --output <PATH>Output binary path (default: .perry-dev/<entry-stem>)
--watch <DIR>Extra directories to watch (comma-separated or repeated)
--Separator — everything after is forwarded to the compiled binary

How it works:

  1. Resolves the entry, computes the project root (walks up until it finds a package.json or perry.toml; falls back to the entry’s parent directory).
  2. Does an initial perry compile, then spawns the resulting binary with stdio inherited.
  3. Watches the project root (plus any --watch dirs) recursively using the notify crate. A 300 ms debounce window collapses editor “save storms” into one rebuild.
  4. On each relevant change: kill the running child, recompile, relaunch. A failed build leaves the old child dead and waits for the next change; no crash loop.

What counts as a “relevant” change:

  • Trigger extensions: .ts, .tsx, .mts, .cts, .json, .toml
  • Ignored directories (not watched, never retrigger): node_modules, target, .git, dist, build, .perry-dev, .perry-cache

Benchmarks (trivial single-file program, macOS):

PhaseTime
Initial build (cold — runtime + stdlib rebuilt by auto-optimize)~15 s
Post-edit rebuild (hot libs cached on disk)~330 ms

The speedup on hot rebuilds comes from Perry’s existing auto-optimize library cache. Multi-module projects will still recompile every changed module on each save — see the V2 note below for planned incremental work.

Not yet in scope (V2+):

  • In-memory AST cache (reuse SWC parses across rebuilds).
  • Per-module .o cache on disk (only re-codegen the changed module).
  • State preservation across rebuilds / HMR — “fast restart” is the honest target.

check

Validate TypeScript for Perry compatibility without compiling.

perry check src/
FlagDescription
--check-depsCheck node_modules for compatibility
--deep-depsScan all transitive dependencies
--allShow all issues including hints
--strictTreat warnings as errors
--fixAutomatically apply fixes
--fix-dry-runPreview fixes without modifying files
--fix-unsafeInclude medium-confidence fixes
# Check a single file
perry check src/index.ts

# Check with dependency analysis
perry check . --check-deps

# Auto-fix issues
perry check . --fix

# Preview fixes without applying
perry check . --fix-dry-run

init

Create a new Perry project.

perry init my-project
cd my-project
FlagDescription
--name <NAME>Project name (defaults to directory name)

Creates perry.toml, src/main.ts, and .gitignore.

doctor

Check your Perry installation and environment.

perry doctor
FlagDescription
--quietOnly report failures

Checks:

  • Perry version
  • System linker availability (cc/MSVC)
  • Runtime library
  • Project configuration
  • Available updates

explain

Get detailed explanations for error codes.

perry explain U001

Error code families:

  • P — Parse errors
  • T — Type errors
  • U — Unsupported features
  • D — Dependency issues

Each explanation includes the error description, example code, and suggested fix.

publish

Build, sign, and distribute your app.

perry publish macos
perry publish ios
perry publish visionos
perry publish android
Argument / FlagDescription
macosBuild for macOS (App Store/notarization)
iosBuild for iOS (App Store/TestFlight)
visionosBuild for visionOS
androidBuild for Android (Google Play)
linuxBuild for Linux (AppImage/deb/rpm)
--server <URL>Build server (default: https://hub.perryts.com)
--license-key <KEY>Perry Hub license key
--project <PATH>Project directory
-o, --output <PATH>Artifact output directory (default: dist)
--no-downloadSkip artifact download

Apple-specific flags:

FlagDescription
--apple-team-id <ID>Developer Team ID
--apple-identity <NAME>Signing identity
--apple-p8-key <PATH>App Store Connect .p8 key
--apple-key-id <ID>App Store Connect API Key ID
--apple-issuer-id <ID>App Store Connect Issuer ID
--certificate <PATH>.p12 certificate bundle
--provisioning-profile <PATH>.mobileprovision file (iOS)

Android-specific flags:

FlagDescription
--android-keystore <PATH>.jks/.keystore file
--android-keystore-password <PASS>Keystore password
--android-key-alias <ALIAS>Key alias
--android-key-password <PASS>Key password
--google-play-key <PATH>Google Play service account JSON

On first use, publish auto-registers a free license key.

setup

Interactive credential wizard for app distribution, plus toolchain setup for Windows.

perry setup          # Show platform menu
perry setup macos    # macOS setup (signing credentials)
perry setup ios      # iOS setup (signing credentials)
perry setup visionos # visionOS setup (signing credentials)
perry setup android  # Android setup (signing credentials)
perry setup windows  # Windows toolchain (downloads MS CRT + Windows SDK via xwin)

perry setup windows downloads the Microsoft CRT + Windows SDK libraries (~1.5 GB) so Perry can link without Visual Studio Build Tools. Requires LLVM (winget install LLVM.LLVM) and prompts to accept the Microsoft redistributable license — pass --accept-license to skip the prompt for CI. Output lands at %LOCALAPPDATA%\perry\windows-sdk. See the Windows platform guide for the full toolchain comparison.

Credential wizards store their output in ~/.perry/config.toml.

update

Check for and install Perry updates.

perry update             # Update to latest
perry update --check-only  # Check without installing
perry update --force       # Ignore 24h cache

Update sources (checked in order):

  1. Custom server (env/config)
  2. Perry Hub
  3. GitHub API

Opt out of automatic update checks with PERRY_NO_UPDATE_CHECK=1 or CI=true.

i18n

Internationalization tools for managing locale files and extracting localizable strings.

perry i18n extract

Scan source files and generate/update locale JSON scaffolds:

perry i18n extract src/main.ts

Detects string literals in UI component calls (Button, Text, Label, etc.) and t() calls. Creates locales/*.json files based on the [i18n] config in perry.toml.

See the i18n documentation for full details.

Next Steps