Skip to main content
This guide will walk you through running your first JavaScript programs with Porffor and exploring its different compilation modes.

Running Your First Script

Let’s start with a simple “Hello World” example:
1

Create a JavaScript file

Create a file called hello.js:
hello.js
console.log('hello world!');
2

Run it with Porffor

Execute the script using the porf command:
porf hello.js
You should see the output:
hello world!
By default, porf compiles your JavaScript to WebAssembly and immediately executes it.

Using the REPL

Porffor includes an interactive REPL (Read-Eval-Print Loop) for experimenting with JavaScript:
porf
This opens an interactive prompt where you can type JavaScript code and see immediate results:
> const x = 42;
> console.log(x * 2);
84
> Math.sqrt(144)
12
Press Ctrl+C twice or type .exit to quit the REPL.

Compilation Modes

Porffor supports multiple compilation targets. Here’s how to use each one:

Compile to WebAssembly

Generate a standalone .wasm file:
porf wasm script.js output.wasm
The generated WebAssembly file doesn’t use a standard import system like WASI, so it may have limited portability on its own.

Compile to C

Compile JavaScript to C code using Porffor’s 2c compiler:
# Output to file
porf c script.js output.c

# Print to stdout
porf c script.js

Compile to Native Binary

Create a standalone executable binary:
# Unix/Linux/macOS
porf native script.js output

# Windows
porf native script.js output.exe
Native binaries are compiled with Clang at Ofast optimization level by default and are automatically stripped for smaller file sizes.

Customizing Native Compilation

Control the compiler and optimization level:
# Use GCC instead of Clang
porf native script.js output --compiler=gcc

# Use Zig compiler
porf native script.js output --compiler=zig

# Set optimization level
porf native script.js output --cO=O3
porf native script.js output --cO=O2
porf native script.js output --cO=O0  # No optimization

Working with TypeScript

Porffor can compile TypeScript files with type annotations:
1

Create a TypeScript file

Create example.ts with type annotations:
example.ts
type i32 = number;
type bytestring = string;

const greet = (name: bytestring): void => {
  console.log('Hello, ' + name + '!');
};

greet('Porffor');
2

Compile with type parsing

Use the --parse-types flag to enable TypeScript support:
porf --parse-types example.ts
3

Enable type optimizations

Use --opt-types to leverage type hints for better performance:
porf --parse-types --opt-types example.ts
Porffor parses type annotations but does not perform type checking. The --opt-types flag uses types as compiler hints for optimization.

Real-World Examples

Here are some practical examples from Porffor’s benchmark suite:

Performance Timing

loops.js
const data = new Array(5000).fill(0).map(() => Math.random());

let t1 = performance.now();
let sum1 = 0;
for (let x of data) {
  sum1 += x;
}
console.log('for..of', performance.now() - t1);

let t2 = performance.now();
let sum2 = 0;
for (let i = 0; i < data.length; i++) {
  sum2 += data[i];
}
console.log('for (let i = 0; i < data.length; i++)', performance.now() - t2);
porf loops.js

String Methods

strings.js
const str = 'The quick brown fox jumps over the lazy dog';
const iterations = 8000;

console.time('toUpperCase');
for (let i = 0; i < iterations; i++) {
  str.toUpperCase();
}
console.timeEnd('toUpperCase');

console.time('toLowerCase');
for (let i = 0; i < iterations; i++) {
  str.toLowerCase();
}
console.timeEnd('toLowerCase');
porf strings.js

Compiler Options

Porffor provides several flags to customize compilation:

Parser Selection

# Use Acorn (default)
porf script.js --parser=acorn

# Use Babel parser (better TypeScript support)
porf script.js --parser=@babel/parser

# Use Meriyah
porf script.js --parser=meriyah

# Use Hermes parser
porf script.js --parser=hermes-parser
When using --parse-types without specifying a parser, Porffor automatically defaults to @babel/parser.

Value Type

Choose the internal value representation:
# Use f64 (default, recommended)
porf script.js --valtype=f64

# Use i32 (experimental)
porf script.js --valtype=i32

Optimization Levels

Control compilation optimizations:
porf script.js -O0
# Disables all optimizations

Advanced Features

Profiling

Profile your JavaScript code to identify performance bottlenecks:
porf profile script.js
Profiling is an experimental WIP feature and may not work correctly for all programs.

Debugging

Debug compiled JavaScript:
porf debug script.js
The debugger is a very experimental feature and has limited functionality.

Tips for Writing Porffor-Compatible Code

Since Porffor is experimental and has limitations, keep these tips in mind:

Avoid async/await

Promise and async/await support has known bugs. Use synchronous code when possible.

Use explicit types

When writing TypeScript, use explicit type annotations to help the compiler optimize your code.

Check examples

Look at the files in the bench directory of the Porffor repository for working examples.

Keep it simple

Porffor supports a subset of JavaScript. Start with simple programs and gradually add complexity.

Common Issues

Limited API Support

Many JavaScript APIs are not yet implemented. If you encounter errors about unsupported features:
  • Check if the API or language feature is listed in the current limitations
  • Look for alternative approaches using supported features
  • Consider filing an issue on the Porffor GitHub repository

Scope Limitations

Variables cannot be accessed between scopes (except arguments and globals):
// This won't work
function outer() {
  let x = 42;
  function inner() {
    console.log(x); // Error: x not accessible
  }
}

// This works
let x = 42; // Global
function test() {
  console.log(x); // OK
}

No Dynamic Code Evaluation

eval() and Function() are not supported due to AOT compilation:
// These won't work
eval('console.log("hello");');
new Function('x', 'return x * 2');

Next Steps

Now that you understand the basics of using Porffor, explore more:

GitHub Repository

View the source code, examples, and contribute to the project

Join Discord

Ask questions and get help from the Porffor community

Build docs developers (and LLMs) love