TypePHP has opened an unusual new path for the PHP ecosystem: compiling PHP code ahead of time into native machine code, without subsequently executing compiled functions as Zend opcodes. Developed by the Swoole team, the project uses PHP as its input language, generates C++17, and ultimately produces executables, PHP extensions, or shared libraries that can run directly on the processor.

The key points about TypePHP in 20 seconds

  • TypePHP is an Ahead-of-Time compiler that converts PHP into C++17 and then into machine code.
  • It can generate executables, PHP extensions, and shared libraries.
  • The compiler itself is written in PHP and can compile itself.
  • Its internal benchmarks show improvements of around 6.5 to 8 times in PHP tests.
  • It does not currently claim compatibility with every existing PHP application.

The proposal is particularly interesting because it does not attempt to replace PHP with another language. Developers continue writing PHP, although they can add type information and specific data structures when they need more performance.

That makes TypePHP quite different from projects such as TypeScript. While TypeScript is ultimately converted back into JavaScript to run inside a JavaScript engine, TypePHP takes part of the code all the way down to native instructions that can be executed by the CPU.

Nor is PHP JIT an exact comparison. OPcache, JIT, and TypePHP operate at different stages and pursue different goals.

From PHP to C++17 and Then to Machine Code

PHP normally transforms source code into opcodes that are executed by the Zend Engine. OPcache avoids repeating part of that work by storing compiled bytecode, while the JIT introduced with PHP 8 can transform certain parts into machine code at runtime.

TypePHP takes another approach: it performs this work before the application is executed.

In simplified form:

PHP
  ↓
Parsing and validation
  ↓
C++17
  ↓
Native compiler
  ↓
Machine code

The actual process also includes .stub.php declarations, optional C or C++ sources, reusable object caches, and precompiled headers.

According to the project’s documentation, TypePHP can currently produce several types of output:

ModeOutputTypical use
binNative executableCLI tools, services, and standalone applications
ext.so or .dll extensionAdding compiled code to PHP
libShared libraryReusing compiled APIs
WASIWebAssembly componentWASI and browser environments

The bin mode is probably the easiest way to understand the conceptual change.

A PHP application compiled this way can start as a native executable without first launching php from the command line.

That does not mean the PHP ecosystem disappears completely. Depending on the build mode and application, binaries can still depend on PHPX, libphp, and other libraries configured during compilation.

TypePHP does not eliminate Zend from every scenario either.

Dynamic PHP features, internal functions, certain objects, reflection, and other components can interoperate with Zend through PHPX, the layer the project uses to connect both environments.

The difference is that user functions compiled by TypePHP no longer need to execute as a sequence of Zend opcodes.

A PHP Compiler Written in PHP

There is another technically interesting detail: TypePHP is written entirely in PHP.

The tpc compiler can compile its own source code using TypePHP. This is known as a self-hosting compiler.

It is more than a curiosity.

A compiler being capable of compiling itself is an important architectural milestone because it requires the supported language to be capable enough to implement something as complex as the compiler itself.

The project states that it does not rely on C or C++ glue code to implement the compiler. C++ appears as an intermediate generated language during compilation.

A basic project can install TypePHP through Composer:

composer require --dev swoole/typephpCode language: JavaScript (javascript)

It can then be compiled with:

vendor/bin/tpc.php project.yml

The repository can also be cloned and run directly:

git clone https://github.com/swoole/typephp.git
cd typephp
composer install
php bin/tpc.php --helpCode language: PHP (php)

On Linux, the build environment requires PHP 8.4 or 8.5, a C++17-compatible compiler, CMake 3.24 or newer, Composer 2, and several additional libraries depending on the features being used.

On Debian and Ubuntu, the basic dependencies listed by the project can be installed with:

sudo apt install build-essential cmake pkg-config libgmp-dev libmpfr-dev

On Fedora, RHEL, and related distributions:

sudo dnf install gcc gcc-c++ cmake pkgconf-pkg-config gmp-devel mpfr-devel

And on Arch Linux:

sudo pacman -S base-devel cmake pkgconf gmp mpfr

Linux x86-64 is currently the primary development and full-test CI platform, although TypePHP also provides targets for Linux ARM64, macOS ARM64, Windows x64, and WASI.

Native Types Are Where TypePHP Tries to Gain Performance

AOT compilation alone does not explain TypePHP’s entire performance proposition.

An important part of the project is its type model.

PHP traditionally maintains considerable runtime flexibility. That flexibility is convenient for development, but it comes with overhead when millions of mathematical operations or data-structure accesses are involved.

TypePHP allows developers to enable:

use native_types;Code language: PHP (php)

From there, certain PHP types can use a much more direct native representation.

For example:

TypePHP typeApproximate C++ representation
intint64_t
floatdouble
boolbool

A simple function such as:

<?php
use native_types;

function fib(int $n): int
{
    if ($n == 1 || $n == 2) {
        return 1;
    }

    return fib($n - 1) + fib($n - 2);
}Code language: HTML, XML (xml)

can therefore be translated into native numerical operations instead of performing every calculation through Zend’s usual dynamic structures.

The project also provides high-precision numerical types such as bigInt, decimal, and bigFloat, backed by GMP, libmpdec, and MPFR respectively.

Typed containers are another part of the approach.

These include:

std::array
std::vector
std::map
std::ordered_mapCode language: CSS (css)

For example:

<?php
use native_types;

function main(): void
{
    $vector = std::vector(Type::Int);

    $vector[] = 10;
    $vector[] = 20;
    $vector[] = 30;

    $sum = 0;

    foreach ($vector as $value) {
        $sum += $value;
    }

    echo $sum . "\n";
}Code language: HTML, XML (xml)

The potential advantage becomes more relevant for algorithms that process large volumes of data.

One benchmark published by the project compared an intensive element-update workload using PHP arrays, TypePHP’s std::array, and C++ std::vector.

ImplementationPublished time
PHP array with JIT67.6 seconds
std::array with TypePHP AOT6.4 seconds
C++ std::vector6.2 seconds

In this particular test, TypePHP was approximately ten times faster than the PHP array implementation and came close to the C++ result.

That figure needs to be interpreted carefully. It is a benchmark published by the project itself and uses a workload particularly suited to static compilation and typed data structures. It does not mean that a WordPress, Laravel, or Symfony application will suddenly run ten times faster simply by using TypePHP.

The documentation also publishes results using bench.php and micro_bench.php, benchmarks included in the PHP source tree:

BenchmarkInterpreted PHPTypePHP AOT -O3Difference
bench.php5.034 s0.603 s~8×
micro_bench.php13.045 s2.021 s~6.5×

Again, these are project measurements rather than performance guarantees for arbitrary applications.

For a web application that spends most of its time waiting for SQL queries, Redis, storage, external APIs, or remote services, accelerating arithmetic operations may produce a much smaller overall improvement.

TypePHP is conceptually more attractive for CPU-intensive workloads: bulk data processing, numerical calculations, batch processing, parsers, report generation, or certain long-running services.

TypePHP vs PHP, OPcache, and JIT

These technologies should not be treated as direct replacements for one another.

TechnologyWhen compilation happensOutputRequires Zend at runtime
Traditional PHPAt executionOpcodesYes
OPcacheStores compiled bytecodeCached opcodesYes
PHP JITDuring executionMachine code for selected pathsYes
TypePHPBefore executionNative codePartially, depending on features used

OPcache continues to make sense for conventional PHP applications.

JIT can also help certain workloads without introducing an additional AOT build process.

TypePHP pursues something different: allowing parts of a software project to be designed from the outset as statically compiled PHP code.

This could be particularly interesting for extensions.

Instead of writing an entire PHP extension in C, TypePHP can compile code as a loadable extension:

bin/tpc.php extension/ -m ext -o my_extension

It can also produce a shared library:

bin/tpc.php lib/ -m lib -o mylib

The ability to combine PHP and C++ extends this model further. TypePHP can declare functions implemented in C++ through .stub.php files and then call them from compiled PHP code.

This creates an intermediate option between writing an entire application in PHP and manually moving performance-critical sections into a C extension.

The Main Limitation: TypePHP Is Not Yet Every Kind of PHP

This is the part that can easily get lost when looking only at the benchmarks.

TypePHP does not claim full PHP compatibility.

The project explicitly states that it implements a defined and tested subset of the language.

Some restrictions are necessary to make AOT compilation possible.

For example, global scope is declaration-only, with executable code placed inside functions or methods. Binary mode also requires a main() function.

A minimal program would look like this:

<?php

function main(): void
{
    echo "Hello World!\n";
}Code language: HTML, XML (xml)

It can then be compiled and executed:

bin/tpc.php hello.php
./hello

Some highly dynamic constructs involving references, reflection, closures, or declarations may still be unsupported.

The project maintains specific documentation covering incompatible PHP features, which any development team should review before considering adoption.

This makes TypePHP much easier to evaluate for new code or computationally intensive modules than as an immediate replacement for a large existing PHP application.

It would also be premature to assume that an entire WordPress, Magento, Drupal, Laravel, or Symfony application can currently be compiled without modification. The heavy use of dynamic behavior, reflection, generated classes, packages, and extensions in these ecosystems requires compatibility to be assessed individually.

There are implications for system administrators as well.

Deployment may no longer consist simply of:

PHP + application

Depending on the selected mode, it can involve:

binary + PHPX + libphp + native libraries

Compatibility between the PHP version, headers, php-config, libphp, ZTS or NTS, and installed extensions therefore becomes important.

The project’s documentation itself warns about ABI problems when components built against different PHP versions or configurations are mixed.

Can TypePHP Protect Source Code?

The project presents another potential benefit: distributing a compiled binary rather than the original PHP files.

This makes recovering the original source code considerably more difficult, although claiming that a binary cannot be decompiled would go too far.

Native binaries can still be examined using reverse-engineering tools, disassemblers, and decompilers. What disappears is the ability to simply open a .php file and read the original source code.

This may be useful for some commercial products, appliances, or software distributed to customers, although product security should never depend solely on hiding its implementation.

Another Step in PHP’s Performance Evolution

TypePHP arrives after several important changes in how PHP executes code.

OPcache reduced the cost of repeatedly compiling scripts. PHP 7 substantially reworked the Zend Engine and improved general performance. PHP 8 introduced JIT. Subsequent versions have continued to improve the language, type system, and engine.

TypePHP now proposes a different path: allowing PHP to partially move beyond its traditional execution model and become software compiled before deployment.

It is still too early to know how much space this approach will find within the broader PHP ecosystem.

Its success will depend on more than impressive benchmarks. The project will need to demonstrate stability, compatibility, debugging tools, integrations, long-term maintenance, and a build experience simple enough to justify introducing another compilation stage.

But the idea has an interesting consequence: PHP could potentially be used to develop components that might previously have been rewritten in C++, Rust, or Go purely for performance reasons.

That does not mean TypePHP will replace those languages. It means that for some workloads, rewriting performance-critical PHP in another language may no longer be the only option when CPU execution becomes the bottleneck.

Frequently Asked Questions

What is TypePHP?

TypePHP is an Ahead-of-Time compiler developed by the Swoole team that transforms PHP code into C++17 and then into native machine code. It can generate executables, PHP extensions, shared libraries, and certain WebAssembly targets.

Does TypePHP replace PHP OPcache or JIT?

Not necessarily. OPcache and JIT operate within PHP’s traditional execution model, while TypePHP compiles code before execution. They are different approaches suited to different types of workloads.

Can TypePHP compile an entire Laravel or WordPress application?

This should not be assumed. TypePHP currently supports a defined subset of PHP and maintains a list of incompatible features. Frameworks and CMS platforms that rely heavily on dynamic behavior need to be tested and evaluated individually.

Is TypePHP ten times faster than PHP?

Not in general. The project has published a specific benchmark in which one of its typed containers was roughly ten times faster than a PHP array with JIT, along with language benchmarks showing improvements of around 6.5 to 8 times. Real-world results depend on the code, CPU, compiler, configuration, and workload.

Sources:

Scroll to Top