Perl 5 → native executable

perla

Compile Perl 5 scripts and modules into standalone native binaries. No perl interpreter required at runtime.

perla parses real Perl, lowers it to Strada, and Strada compiles it to C. You get a single binary you can ship — no CPAN install, no DynaLoader, no libperl dependency.

Get Started Documentation

Why perla?

Real Perl is wonderful for scripting and prototyping. perla is for the moments where you'd rather ship a compiled artifact than a script that depends on a runtime.

📦

Single-binary deploys

One statically-linked executable. No perl to install on the target, no version skew, no CPAN bootstrap, no cpanm on boot. Drop it on a server or into a container and run.

Faster startup

No perl interpreter warm-up. For short-lived scripts and CLI tools that get invoked constantly, the difference between 40ms perl startup and a sub-millisecond native exec matters.

🏎️

Native-code performance

Tight inner loops compile to real machine code. perla's backend is Strada — which consistently outruns Perl, Python, and Ruby on CPU-bound work. You choose the tradeoff: -O0 for fast compiles, -O3 for release.

🔧

Raw C when you need it

__C__ { ... } drops inline C into a Perl sub. FFI to libc, libcurl, zstd, or a custom .so — without writing XS. All of Perl's value for rapid development, all of C's value for the 5% that needs it.

🌐

Web framework ready

Runs well under Cannoli, Strada's preforking web server. perla-compiled handlers load as .so's — see the cannoli_perla bridge for how large-scale apps serve HTTP.

🧠

Keep your Perl brain

Sigils, regex, map/grep/sort, bless, AUTOLOAD, Moose-style has/extends/with, tie, typeglobs, format/write, try/catch — the idioms you know from Perl work here. The most-used modules (JSON, DBI, Carp, List::Util, Encode…) are native; the rest install from CPAN with perla-cpan.

💾

Precompile once, run many

perla -M lib/ builds every module in a tree to .pm.o once. Subsequent compiles of scripts that use them skip re-parsing the source — a big speedup on programs with deep use trees.

🧪

Predictable memory

Reference counting with tagged integers — most data dies deterministically the moment its last reference drops. An automatic cycle collector reclaims indirect cycles (no Scalar::Util::weaken required), and a request arena is available for bump-allocated per-request workloads under Cannoli. Everything is debuggable with valgrind.

The honest edges

perla is mature, not magic. Most Perl compiles unchanged; here's where you still have to think.

What actually compiles

perla isn't a toy subset. It tracks the parts of Perl people really use — the metaprogramming, the text-processing machinery, the modules — backed by 119 feature tests covering everything below.

🧩

Objects & Moose

bless, @ISA, SUPER::, AUTOLOAD, Perl's method resolution order, overload, DESTROY. Plus Moose-style has/extends/with and before/after/around — implemented natively, not via Class::MOP.

🔤

Real regex

m//, s///, tr/// with /e /g /i /x /s, numbered and named captures, lookahead/lookbehind, backreferences, and embedded code (?{ ... }).

🪢

Tie & typeglobs

tie/untie/tied on scalars, hashes, arrays, and filehandles. Typeglob aliasing (*A = *B, *A = \$x), glob derefs, and stash iteration.

🧾

format & write

Perl's report templates, in full: picture fields, top-of-page headers, pagination, per-filehandle formats via select, $^A, and formline.

🌍

Unicode, properly

UTF-8 string semantics with the SVf_UTF8 flag, Unicode::Normalize (NFC/NFD/NFKC/NFKD), Encode transcoding, and UTF-8-aware substr/split/chop.

🔢

Numbers that match Perl

Tagged 64-bit integers, unsigned 64-bit (UV) arithmetic with overflow promotion, NVs, hex/oct, and srand/rand that's bit-for-bit compatible with perl.

⛓️

Modern Perl

try/catch (5.34) with a bound error variable, state variables, chained comparisons (5.32), goto LABEL, lvalue substr, and local on slices.

📚

Batteries included

Native, no install: JSON, DBI (SQLite / MySQL / MariaDB / PostgreSQL), Carp, Data::Dumper, List::Util, Scalar::Util, Storable, Encode, File::Temp, Digest::*, MIME::Base64, Time::HiRes.

📥

CPAN when you need it

perla-cpan Module::Name fetches from MetaCPAN, resolves transitive dependencies, and compiles XS — pure-Perl and C-extension modules alike, no DynaLoader required.

Example

This is just Perl.

Compile, run, ship. No preamble, no type annotations, no IDE setup.

# hello.pl
use strict;
use warnings;
use JSON;

sub greet {
    my ($name) = @_;
    return encode_json({ hello => $name, time => time() });
}

print greet("world"), "\n";
$ perla -O2 -o hello hello.pl
$ ./hello
{"hello":"world","time":1755123456}

$ file hello
hello: ELF 64-bit LSB pie executable, x86-64, statically linked

That's the entire workflow. perla reads your .pl, resolves its use tree, lowers it to Strada, compiles to C, and links a binary. No cpanm install JSON, no Carton bundling, no fatpack. The JSON encoder is wired into perla's runtime as a native module.

Get started

Install Strada, build perla against it, then compile any Perl file.

# 1. build & install Strada
$ git clone https://github.com/strada-lang/strada-lang
$ cd strada-lang && ./configure && make && sudo make install

# 2. build perla against the system Strada
$ git clone https://github.com/strada-lang/perla
$ cd perla && make && sudo make install

# 3. compile any Perl file
$ echo 'print "hi\n"' > hi.pl
$ perla hi.pl
hi
Full Getting Started Guide