TypePHP is Swoole’s ahead-of-time (AOT) compiler: you write typed PHP, it lowers the program to C++17, then produces a native binary, PHP extension, or shared library. That path is not “faster OPcache,” and it is not the same product as long-running Swoole workers or FrankenPHP. It is a compile step that trades dynamic PHP flexibility for native machine code on the hot path.
This guide covers what TypePHP is, how it differs from OPcache and JIT, the official language-benchmark numbers from the project README, a practical Linux install path, the three compile modes, who should adopt it (and who should not), compatibility limits, and measured Cloud VPS sizing from our own toolkit measurements. Official docs live under swoole.com/aot; the source of truth for the compiler is github.com/swoole/typephp. Do not confuse this project with unrelated “TypePHP” pages that discuss runtime typing notes only.
What TypePHP is
Classic PHP executes through the Zend engine: parse → opcodes → (optional OPcache) → (optional JIT traces) → run. TypePHP changes the delivery model. Compatible typed PHP is translated once into optimized C++17, then linked against PHPX and (depending on mode) libphp / Embed SAPI pieces. The output can be a standalone executable that starts without invoking php as a separate interpreter process, a loadable extension, or a library other projects call.
The project targets PHP 8.4–8.5, requires a C++17 toolchain (GCC 9+ / Clang, or MSVC on Windows), CMake 3.24+, Composer 2, and high-precision math libraries (GMP, MPFR). Binary mode on Unix expects a matching Embed library (libphp.so / libphp.dylib); if it is missing, the build can offer php-builder to compile a private runtime from php-src. That auto-build is the heavy path for RAM and disk.
TypePHP is still young relative to FPM WordPress hosting. Treat it as a compiler for CPU-bound CLI tools, typed hot paths, native packaging, and source protection — not as a drop-in “make my CMS 8× faster” switch.
TypePHP vs OPcache vs JIT vs Swoole / FrankenPHP
These tools solve different problems. Mixing the marketing slogans is how teams waste a sprint.
| TypePHP AOT | OPcache | JIT (PHP 8+) | Swoole / FrankenPHP | |
|---|---|---|---|---|
| Compilation target | Native machine code (via C++17) | Bytecode | Machine code (trace-based) | Still Zend/runtime; long-lived process |
| Warm-up | None at runtime (already compiled) | Per-process warm-up | JIT warm-up | Worker boot + connection reuse |
| Native executable | Yes (bin mode) | No | No | No (unless you wrap the binary yourself) |
| Typical win | Numeric / typed hot paths, packaging | Avoid reparse every request | Some CPU loops in PHP | Concurrency, persistent connections, fewer process forks |
OPcache keeps opcodes in shared memory so PHP does not reparse files every request. JIT can emit machine code for hot traces inside the same Zend process. Neither ships a standalone native product binary. Swoole and FrankenPHP keep PHP resident and change how you handle I/O and concurrency; they do not AOT-compile your app into C++. TypePHP’s job is AOT native output. You can still use Swoole extensions where supported, but “run Swoole” and “compile with TypePHP” are different decisions.
Official benchmark numbers (and what they do not prove)
The TypePHP README publishes language benchmarks from php-src’s bench.php and micro_bench.php, compiled with -O3:
bench.phptotal: 5.034 s (interpreted PHP) → 0.603 s (TypePHP AOT) — about ~8×micro_bench.phptotal: 13.045 s → 2.021 s — about ~6.5×
Those workloads stress function calls, object property access, array/hash access, strings, and control flow. They are not WordPress page-generation benches, not Laravel HTTP throughput, and not a promise that your existing CMS will get the same multiplier after a weekend migration. The README itself labels the table a project measurement snapshot: PHP version, CPU, flags, and extensions all move the result. Compare on the same machine before you plan capacity.
A separate std-container microbench in the same README shows PHP arrays under JIT at 67.6 s versus TypePHP std::array at 6.4 s (near a hand-written C++ std::vector at 6.2 s) for a large update loop. That is interesting for numeric/container work; it still is not a CMS TTFB claim. Performance docs that say “more than 10× vs ZendVM” should be read as marketing-adjacent language for friendly workloads — keep the README table as the primary cited numbers in this article.
Installation on Linux
Two practical paths exist: Composer package, or a prebuilt tpc release binary from GitHub.
System packages
sudo apt update
sudo apt install -y build-essential cmake pkg-config libgmp-dev libmpfr-dev
# PHP 8.4 or 8.5 CLI + development headers + php-config
# Composer 2
RHEL/Fedora use dnf install gcc gcc-c++ cmake pkgconf-pkg-config gmp-devel mpfr-devel. You need CMake ≥ 3.24.
Composer
composer require --dev swoole/typephp
vendor/bin/tpc.php project.yml
# or: vendor/bin/tpc.php hello.php
Release binary and PHPX / libphp
Linux release archives ship the compiler (and READMEs); production Composer dependencies are embedded in tpc. Match the archive’s PHP ZTS ABI to the host PHP. Set PHP_HOME to a prefix with bin/php-config, headers, and lib/libphp.so when building binary/shared outputs. PHPX_HOME can point at a PHPX install. If Embed libphp is missing, TypePHP may offer to build it via php-builder from php-src — plan RAM and disk for that (see sizing below).
Official install / Composer / compile / execution docs: Install, Composer, Compile, Execution.
Windows note
Windows x64 toolkits bundle matching PHP/PHPX runtimes. You still need a supported C++ compiler (MSVC). Set PHP_HOME, PHPX_HOME, and PATH per the toolkit’s WINDOWS-SETUP.txt. Linux remains the primary CI and production compile host for most teams.
Hello world and three compile modes
<?php
function main(): void
{
echo "Hello World!\n";
var_dump(PHP_VERSION);
}
bin/tpc.php hello.php
./hello
Binary mode requires a global main() (no parameters, or main(int $argc, array $argv), returning void). Top-level executable statements are not allowed; put work inside functions or methods.
| Mode | Flag | Output | Needs main() | Typical use |
|---|---|---|---|---|
| Binary | -m bin (default) | Executable | Yes | CLI tools, services, standalone apps |
| Extension | -m ext | PHP .so / .dll | No | Load compiled APIs into a PHP SAPI |
| Library | -m lib | Shared library + stubs | No | Reuse from another project |
There is also --nano for VM-free Nano builds that do not link libphp and reject eval / dynamic includes — a stricter subset for native packaging. Start with normal bin mode unless you know you need Nano.
Who should use TypePHP — and when not to migrate
Good fit: CPU-bound CLI utilities, batch processors, typed numeric pipelines, tools you want to ship as a native binary, teams already comfortable with C++ toolchains and PHP 8.4+, experiments where you control the source and can rewrite dynamic patterns.
Poor fit: Classic FPM WordPress or “compile the whole Laravel app tomorrow,” shared hosting without root/toolchain, codebases that lean on eval, heavy runtime class generation, or reflection tricks TypePHP intentionally rejects. TypePHP is not a magic accelerator you drop in front of an unchanged CMS.
Migration decision in one sentence: if your win depends on typed hot paths and you can accept AOT constraints, prototype a small CLI binary; if your win depends on HTTP framework plugins and dynamic WordPress filters, stay on OPcache/JIT (and consider Swoole/FrankenPHP only for concurrency — not as an AOT substitute).
Compatibility limits
TypePHP follows PHP syntax where it is compatible with AOT, with deliberate restrictions. Global scope is declaration-only. Inferred int/float/bool use fixed native storage by default. Some highly dynamic reference, declaration, closure, and reflection patterns remain unsupported. Always check the project’s incompatible-features list and the compatibility docs before promising a rewrite. Selling “we will TypePHP your existing CMS” without an audit is how you get stuck mid-migration.
Try it on a EuroVDC Cloud VPS (measured minima)
We measured the official Windows TypePHP v0.9.4 toolkit on a build host (Docker/WSL were unavailable on that machine, so Linux auto-build of php-src was not run there). Recorded numbers:
- Windows toolkit zip: 56.77 MB; extracted on disk: 171.24 MB
- Linux release tarball (compiler-oriented asset): 12.53 MB
- Peak working set of
tpc.exewhile attemptinghello.phpcompile: 34.6 MB (compile then stopped because MSVCclwas not installed on that host — the RSS peak still reflects compiler startup cost)
For a real Linux experiment with system packages, prebuilt tpc, and a C++ toolchain, plan at least:
- ≥ 4 GB RAM, 2+ vCPU, ≥ 20 GB free disk → EuroVDC Cloud VPS Medium (4 vCPU / 4 GB) as the practical floor
- If you enable
php-builder/ Embedlibphpauto-build from php-src with a comfortable-j: ≥ 8 GB RAM → Cloud VPS Medium Plus (4 vCPU / 8 GB) - Shared hosting: not suitable (no toolchain, no root, no Embed library control)
Order a European node on Cloud Server, install the packages above, and compile a hello binary before you commit a product rewrite. Soft path check from our Sofia datacenter: Looking Glass.
References
- swoole/typephp — README, requirements, benchmark table
- TypePHP installation (swoole.com/aot)
- Composer integration
- Compile documentation
- Performance documentation
- Compatibility documentation
- Execution documentation
- ITNEXT — TypePHP wants to make PHP faster
- Codex — Getting to Know TypePHP
Ready to experiment? Provision Cloud VPS Medium or Medium Plus, install the toolchain, compile hello.php, then decide whether your hot path belongs in AOT TypePHP or stays on OPcache/JIT.