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

Platform Targets

Perry compiles TypeScript to native binaries for multiple platforms. Each target uses platform-specific UI libraries and rendering backends.

Supported Platforms

PlatformTarget FlagUI LibraryRendering Backend
macOS(default, no flag)perry-ui-macosMetal, CoreGraphics, CoreText
iOS--target ios-simulatorperry-ui-iosUIKit, CoreGraphics, CoreText
Windows--target windowsperry-ui-windowsDirect2D, DirectWrite, DirectComposition
Linux--target linuxperry-ui-linuxCairo, Pango
Android--target androidperry-ui-androidAndroid NDK
Web--target web(WASM)WebAssembly, Canvas/WebGL

Compile-Time Platform Detection

Perry provides the __platform__ compile-time constant. Code guarded by platform checks is dead-code-eliminated for non-matching platforms.

ValuePlatform
0macOS
1iOS
2Android
declare const __platform__: number;

function getDefaultFontSize(): number {
  if (__platform__ === 0) {
    return 13;  // macOS — standard desktop size
  } else if (__platform__ === 1) {
    return 16;  // iOS — larger for touch
  } else if (__platform__ === 2) {
    return 16;  // Android — larger for touch
  }
  return 13;
}

Because __platform__ is resolved at compile time, the non-matching branches are stripped entirely from the binary. This means platform-specific imports and FFI calls in dead branches do not need to link.

Per-Platform FFI Crates

Each platform has dedicated Rust crates that implement the FFI functions using native APIs. These crates all export the same __wrapper_* symbols, so TypeScript code remains platform-agnostic.

Editor FFI crates:

PlatformCrateKey APIs
macOShone-editor/native/macos/CoreText for text shaping, Metal for GPU rendering
iOShone-editor/native/ios/CoreText for text, UIKit for input
Windowshone-editor/native/windows/DirectWrite for text, Direct2D for rendering
Linuxhone-editor/native/linux/Pango for text, Cairo for rendering
Androidhone-editor/native/android/Android NDK Canvas, Skia

Terminal FFI crates follow the same pattern in hone-terminal/native/.

Compilation Examples

# macOS (default target)
perry compile src/app.ts --output hone-ide

# iOS Simulator
perry compile src/app.ts --target ios-simulator --output Hone

# Web
perry compile src/app.ts --target web --output hone-ide.html

UI Testing by Platform

macOS — geisterhand

geisterhand is the UI automation tool for macOS Perry binaries.

# Capture screenshot
geisterhand screenshot --output /tmp/shot.png

# Click at pixel coordinates
geisterhand click 200 350

# Type text
geisterhand type "hello world"

iOS Simulator — AppleScript

For iOS Simulator targets, use osascript (AppleScript) to drive the Simulator app:

# Tap at coordinates in Simulator
osascript -e 'tell application "Simulator" to activate'
# Use Accessibility APIs or xcrun simctl for interaction

geisterhand does not work with the iOS Simulator — it only targets native macOS windows.

Output Artifacts

TargetOutputSize (typical)
macOSStatic binary5-15 MB
iOS.app bundle8-20 MB
Web.html + .wasm2-5 MB
Auth server (macOS)Static binary~2.8 MB

All native binaries are statically linked — no runtime dependencies, no Node.js, no V8. The binary includes the Perry stdlib, platform UI library, and all FFI crates.