Hello World
Your First Program
Create a file called hello.ts:
console.log("Hello, Perry!");
Compile and run it:
perry hello.ts -o hello
./hello
Output:
Hello, Perry!
That’s it. Perry compiled your TypeScript to a native executable — no Node.js, no bundler, no runtime.
A Slightly Bigger Example
function fibonacci(n: number): number {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
const start = Date.now();
const result = fibonacci(40);
const elapsed = Date.now() - start;
console.log(`fibonacci(40) = ${result}`);
console.log(`Completed in ${elapsed}ms`);
perry fib.ts -o fib
./fib
This runs about 2x faster than Node.js because Perry compiles to native machine code with integer specialization.
Using Variables and Functions
const name: string = "World";
const items: number[] = [1, 2, 3, 4, 5];
const doubled = items.map((x) => x * 2);
const sum = doubled.reduce((acc, x) => acc + x, 0);
console.log(`Hello, ${name}!`);
console.log(`Sum of doubled: ${sum}`);
Async Code
async function fetchData(): Promise<string> {
const response = await fetch("https://httpbin.org/get");
const data = await response.json();
return data.origin;
}
const ip = await fetchData();
console.log(`Your IP: ${ip}`);
perry fetch.ts -o fetch
./fetch
Perry compiles async/await to a native async runtime backed by Tokio.
What the Compiler Produces
When you run perry file.ts -o output, Perry:
- Parses your TypeScript with SWC
- Lowers the AST to an intermediate representation (HIR)
- Applies optimizations (inlining, closure conversion, etc.)
- Generates native machine code with Cranelift
- Links with your system’s C compiler
The result is a standalone executable with no external dependencies.
Binary Size
| Program | Binary Size |
|---|---|
| Hello world | ~300KB |
| CLI with fs/path | ~3MB |
| UI app | ~3MB |
| Full app with stdlib | ~48MB |
Perry automatically detects which runtime features you use and only links what’s needed.