Skip to main content
Porffor uses a fundamentally different approach to executing JavaScript compared to traditional engines like V8 or SpiderMonkey. Instead of using a JIT (Just-In-Time) compiler or interpreter, Porffor is 100% AOT (Ahead-Of-Time) compiled.

What is AOT Compilation?

AOT compilation means that your JavaScript code is compiled entirely to WebAssembly (or native code) before execution, not during runtime. This is in contrast to:
  • Interpreters: Execute code line-by-line at runtime (slow but simple)
  • JIT compilers: Compile hot code paths during execution (fast after warmup)
  • AOT compilers: Compile everything before execution (fast from the start)
// Code is parsed, interpreted initially,
// then JIT-compiled during execution
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

// First few calls: interpreted (slow)
// Later calls: JIT-compiled (fast)
fibonacci(10);

Key Characteristics

Zero Runtime/Preluded Code

Porffor generates WebAssembly with zero constant runtime or preluded code. Every piece of code in the output is generated specifically for your program:
Only the code you write and the builtins you use are included
No heavy runtime library shipped with every program
Minimal WebAssembly imports (only I/O operations)

Compilation Pipeline

The AOT compilation process follows these steps:
The parser (Acorn) is the only external dependency. Everything else—from bytecode generation to final assembly—is built from scratch.

Compilation Targets

Porffor’s AOT approach enables multiple compilation targets:

WebAssembly

Compile to .wasm files for web or Wasm runtimes

Native Binaries

Compile to native executables via 2c (Wasm → C → binary)

C Source

Generate C code for maximum portability

Direct Execution

Run immediately via Porffor’s runtime

Advantages

Predictable Performance

Unlike JIT engines, performance doesn’t vary based on warmup:
porf script.js
# Fast from the start

Small Output Size

Without a runtime, compiled programs are remarkably small:
# Simple hello world
porf wasm hello.js hello.wasm
ls -lh hello.wasm
# Output: ~200 bytes

Security

AOT compilation provides inherent security benefits:
No dynamic code generation at runtime
All code known and analyzed before execution
Wasm’s sandboxed environment
Memory-safe compilation (JavaScript → Wasm)

Limitations

No Dynamic Code Execution

Because everything is compiled ahead of time, dynamic code evaluation is impossible:
// ❌ Not supported in Porffor
eval('console.log("hello")');
Function('return 42')();

// ✅ Use direct code instead
console.log("hello");
const fn = () => 42;

Limited Runtime Flexibility

JIT engines can optimize based on runtime patterns. Porffor must make all decisions at compile time:
  • Type specialization happens at compile time (not runtime)
  • No dynamic recompilation based on usage patterns
  • Cannot adapt to changing execution patterns

Optimization Levels

Porffor provides multiple optimization levels:
porf -O0 script.js
Disables optimizations. Fastest compilation, larger output.

Type-Guided Optimization

Use TypeScript annotations to help the compiler optimize:
// Enable parsing and optimization with type annotations
// porf --parse-types --opt-types script.ts

function add(a: number, b: number): number {
  return a + b;
}

// Compiler knows types, generates optimized Wasm
Porffor doesn’t type-check your code, but uses type annotations as compiler hints for better optimization.

Comparison with Other Engines

FeaturePorffor (AOT)V8/SpiderMonkey (JIT)QuickJS (Interpreter)
Startup timeInstantSlower (warmup)Instant
Peak performanceGoodExcellentPoor
Binary sizeTinyLargeMedium
Memory usageLowHighMedium
Dynamic eval
PredictabilityHighLowHigh

Performance Characteristics

From the README:
For the features it supports, Porffor is blazingly fast compared to interpreters and engines without JIT. With JIT engines, Porffor can match or exceed performance with compiler arguments, typed input, and native compilation.

Next Steps

Type System

Learn about Porffor’s type system and ByteStrings

Memory Model

Understand memory management and pointers

Compiler Options

Explore all compilation flags

Native Compilation

Compile JavaScript to native executables

Build docs developers (and LLMs) love