PAX: Compiling Perl Again, This Time for Real

2026-04-24

Perl developers have heard "compiled Perl" claims for a long time. Most of them ended in one of three places: a benchmark trick, a startup shortcut or a demo that could not survive real application code.

That history is exactly why PAX is worth looking at carefully instead of cheering too early.

PAX is not a new language and it is not a pitch to replace Perl with something trendier. The point is more specific than that: keep Perl, compile what is actually safe to compile, preserve Perl behavior where the language stays dynamic, package the result into one executable and make eligible hot paths run at native speed.

That is a much harder goal than "transpile a toy script," but it is also the only goal that matters if you want working developers to take the project seriously.

Why This Conversation Usually Fails

Perl is not a shallow language. A real compiler story has to deal with all the things that make Perl powerful and awkward at the same time:

  • context sensitivity
  • runtime symbol table mutation
  • imports with side effects
  • require, eval, caller, prototypes and magic variables
  • top-level script behavior that does not reduce cleanly to one function call

If a tool only works on the easy tenth of the language, it is not solving the problem the Perl community actually has.

That is why most old "compiled Perl" conversations died on contact with production code.

What PAX Is Trying to Do Differently

The important thing about PAX is not that it claims to compile Perl. The important thing is the shape of the system around that claim.

PAX combines:

  • captured Perl code structure and runtime metadata
  • compiled code units where the semantics are understood well enough
  • hybrid units where some parts can compile and some still need a compatibility path
  • embedded assets
  • standalone binary packaging
  • native dispatch for hot regions that qualify

The compact version looks like this:

terminal
Perl app + Perl modules + assets + PAX compiler/runtime
-> one generated executable
-> runs without the source tree
-> can execute eligible hot paths natively

That is a very different target from "make one loop faster."

The Part That Makes It Credible

The strongest idea inside PAX is that it does not force an all-or-nothing compiler fantasy.

Real Perl applications are uneven. Some modules are stable and compiler-friendly. Some are not. Some families of code can be lowered deeply. Others still need a compatibility floor. PAX treats that as a systems boundary to manage instead of pretending the hard parts do not exist.

Right now that shows up in multiple packaged code-unit forms, including compiled units, hybrid compiled units and specialized compiled entrypoint families for scripts and webapp dispatch.

That matters because it gives the project a plausible way to move forward incrementally without throwing the whole application back to "just run the source" every time one module gets weird.

What Already Works

This is the part that changes the tone of the discussion.

PAX can already:

  • build standalone executables
  • use paxfile.yml as a repeatable build contract
  • package compiled and hybrid Perl code units
  • embed assets
  • package native hot-path artifacts
  • use bundled-runtime compatibility where the compiler frontier has not reached a dependency yet

That still would not be enough by itself if it only worked on synthetic cases. The more interesting evidence is that the project already has a real web application path.

The Web App Proof Matters More Than the Benchmark

PAX now supports a reference web application built around the sort of stack Perl developers actually recognize:

  • Dancer2
  • Plack
  • Starman
  • Template Toolkit
  • TT templates
  • CSS
  • JS

That application is built as one standalone binary and the binary still serves the pieces you expect from a real app, including rendered HTML, CSS, JS and a health endpoint.

The build path is concrete:

terminal
perl -Ilib bin/pax standalone-build --compact --paxfile examples/webapp/paxfile.yml

The resulting binary can then be run directly:

terminal
.pax/standalone/pax-webapp/pax-webapp serve --host 127.0.0.1 --port 5000

There is also a proper two-stage Docker story:

terminal
FROM perl-build-image AS build
# install deps, copy repo, build PAX binary

FROM debian:trixie-slim
COPY --from=build /workspace/.pax/standalone/pax-webapp/pax-webapp /app/pax-webapp
ENTRYPOINT ["/app/pax-webapp"]

That stage-two image gets the binary, not a checked-out application tree. For anyone who has spent years shipping Perl by dragging source trees and runtime assumptions through deployment, that is the part worth paying attention to.

There Is Also a Real Speed Story

PAX is not only about packaging. It also has a meaningful hot-path acceleration story.

One measured integer-loop example from the current tree used n = 400000000 and produced these results:

Mode Time
Stock Perl 12.15s
pax run compile-and-run pipeline 2.33s
PAX native artifact direct execution 0.08s

That is not the same thing as saying "all Perl becomes native instantly." It is saying something more defensible:

  • stock Perl pays normal interpreter cost
  • pax run pays compile plus execute cost
  • the generated native artifact shows what the compiled hot region can actually do

That is enough to move the project out of the "interesting idea" bucket and into the "real systems work" bucket.

What Is Done and What Is Not

This part matters because overclaiming would damage the whole effort.

As of April 24, 2026, the current validation evidence includes:

  • perl -Ilib t/standalone_image.t -> 1..86
  • prove -lr t -> Files=18, Tests=332, Result: PASS

The project already has:

  • a standalone binary build pipeline
  • a paxfile.yml-driven build contract
  • compiled and hybrid code-unit packaging
  • packaged native artifact integration
  • embedded assets
  • standalone inspection and extraction tooling
  • native dispatch during standalone execution
  • a working webapp reference path
  • a two-stage Docker binary-only proof

What it does not yet have is universal, source-free compilation for arbitrary Perl application code with no compatibility floor at all.

That remaining gap still sits around:

  • framework-family compilation depth
  • complex top-level entrypoint lowering
  • unsupported hybrid residuals

So the honest reading is this: PAX already works as a real adaptive system, but it has not yet reached its final compiler frontier.

The Goal in One Line

If you compress the whole project down to one sentence, it is this:

Go-style deployment, Perl compatibility, native-speed hot paths.

That line is useful because it captures the actual ambition without pretending the hard parts are already solved.

Why Perl Developers Should Pay Attention Now

For years it was easy to dismiss compiled-Perl claims because the evidence never reached the level of real deployment.

PAX changes that because it is no longer only talking about:

  • loops
  • benchmark artifacts
  • partial compiler theory

It is talking about and demonstrating:

  • real standalone binaries
  • real assets
  • real framework integration
  • real Docker deployment paths
  • real native speedups on eligible code

If you care about Perl but have assumed its deployment and performance story was permanently stuck in an older era, this is the kind of project that deserves a closer look.

Not because it is finished.

Because it has moved beyond being hypothetical.

What Comes Next

The next phase is not more performance theater. It is deeper compiler coverage in reusable ways.

The project still needs:

  • broader framework-family compilation
  • less residual-source activation
  • stronger top-level entrypoint lowering
  • more reusable compiler and runtime improvements instead of one-off escapes

That is the right rule for a project like this. If one module family fails, the answer cannot keep being a one-time patch for one application. The compiler frontier has to move in a way that holds for the next app too.

Closing

PAX matters because it is aiming at the problem Perl developers actually have: how to keep the language, improve deployability and unlock more native-speed execution without pretending Perl's dynamic semantics are easy.

It is not done.

But "compile Perl into something deployable, fast and worth taking seriously" is no longer a joke or a nostalgia thread. It is a live engineering effort with enough real proof behind it to justify attention now.


← back to index