# StaticPHP v3: a statically linked PHP build driven by one craft.yml file

> The project formerly called static-php-cli builds a single file PHP binary with a chosen extension set, driven by the spc tool and a craft.yml manifest. Useful for shipping PHP into containers and minimal systems, and a moving target right now because v3 is the branch you get by default and the name change has not been released yet.

**crazywhalecc/static-php-cli** — Build standalone portable PHP binaries on Linux, macOS, Windows, with PHP project together, with popular extensions included.

- Repository: https://github.com/crazywhalecc/static-php-cli
- Website: https://static-php.dev
- Stars: 1,955 · Forks: 424
- Language: PHP
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/crazywhalecc-static-php-cli

## The project is mid-rename, and the branch name tells you which one you have

Before anything else, the README carries a notice that changes how you should treat the repository. It states that the maintainers are preparing to release v3, which will include a project rename from static-php-cli to StaticPHP, and that the branch in use is the one for v3, with v2 on a separate branch.

The default branch is v3. So a clone without arguments gives you the unreleased line, not the released line. That is the first thing to verify before pinning a version in your own pipeline.

The project is MIT licensed, and the licence section adds a caveat that is easy to skim past: the project itself is MIT, but some newly added extensions and dependencies may originate from other sources. For a tool whose entire job is compiling other people's C code into a binary, that sentence carries more weight than a normal dependency notice.

## spc is downloaded as a nightly binary, not installed from a package manager

The build tool is a single executable called spc, described in the feature list as self-contained for easy self-installation. Getting it is a direct download, with one URL per platform:

```bash
# For Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-aarch64
# Windows (x86_64, win10 build 17063 or later, please install VS2022 first)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/v3/spc-bin/nightly/spc-windows-x64.exe
```

Two details are easy to miss. The path contains nightly, so the tool you fetch changes without a version number. And the Windows entry carries two prerequisites in the comment itself: a Windows 10 build of 17063 or later, and Visual Studio 2022 installed beforehand.

On macOS and Linux you add execute permission before running it:

```bash
chmod +x ./spc
```

## craft.yml is the whole build description

The build is driven by a file called craft.yml, created by hand or generated from the online command generator the README links to. The example it gives names a PHP version, a comma separated extension list, the SAPIs to build and a download concurrency:

```yml
# PHP version support: 8.1, 8.2, 8.3, 8.4, 8.5, 8.6 (pre-release)
php-version: 8.5
extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
sapi:
  - cli
  - micro
download-options:
  parallel: 10
```

Three things are decided here and nowhere else. The PHP version, which spans 8.1 through 8.5 with 8.6 marked pre-release. The extension set, which is the single most consequential choice for the resulting binary. And the SAPIs, where cli is the plain interpreter and micro is the self-extracting variant.

The feature list claims support for 100 or more popular PHP extensions, and the extension list and command generator pages are the place to find the current set. spc.registry.yml at the repository root is the registry the tool reads.

## Two run modes, and micro:combine produces a single executable

The build itself is one command, with a verbosity flag for when it fails:

```bash
./spc craft

# Output full console log
./spc craft -vvv
```

Using the result is where the two SAPIs diverge. The cli output is a normal interpreter you copy to another machine:

```bash
buildroot/bin/php -v
```

The micro output combines the interpreter and your source into one file, using phpmicro:

```bash
echo '<?php echo "Hello world!\n";' > a.php
./spc micro:combine a.php -O my-app
./my-app
```

The second form is the one that changes deployment. A phpmicro artifact is a self-extracting executable, so a single file is the whole application. That is the shape most container and CLI distribution work wants, and it is why the project lists phpmicro as a headline feature alongside the single file php-cli build.

The feature list also mentions UPX compression support, which the README says reduces binary size by 30 to 50 percent.

## Prebuilt artefacts come in two sizes, and they differ by ten times

If you want to try the tool before building, the README points to example pre-compiled artefacts from GitHub Actions. Two extension sets are offered for each PHP version, and the size difference is the point:

- gigantic, which includes as many extensions as possible and lands at about 100 to 150MB.
- base, which includes only a few extensions used by StaticPHP itself and lands at about 10MB.

That ratio is the single most useful number in the README for anyone doing capacity planning. A 10MB binary and a 150MB binary are not variants of the same thing, they are different deployment profiles, and the base set tells you what a minimal static PHP looks like in practice.

When the prebuilt sets do not fit, the README describes building through GitHub Actions instead: fork the repository, open the Actions of the project, select CI, then use Run workflow and fill in the PHP version, the target type and a comma separated extension list such as bcmath,curl,mbstring. When the run finishes you open it and download the Artifacts. Enabling debug makes all logs output at build time, including compiler logs, which is the documented troubleshooting path.

## The repository is a PHP tool with a documentation site and a full QA stack

The top level listing shows the project is more than a build script. Source lives in src/ and bin/, with config/ holding configuration, spc.registry.yml the registry, and ext-support.md a note on extension support.

The repository includes phpunit.xml.dist, phpstan.neon,.php-cs-fixer.php, captainhook.json, and box.json. composer.json and composer.lock are present, along with.editorconfig and an AGENTS.md plus an.agents/ directory.

Documentation is a VitePress site under docs/, with its own package.json:

```json
"docs:build": "node docs/.vitepress/gen-meta.js && vitepress build docs"
```

Note the first half of that script: navigation metadata is generated before the site builds, which is why editing a doc page still requires a regeneration step. Full documentation lives at static-php.dev. The README is explicit that it contains basic usage only.

## Where this is the wrong tool

StaticPHP produces one interpreter for one platform. The download URLs are per architecture and per operating system, so a fleet spanning Linux x86_64, Linux aarch64 and Windows needs three builds of the same PHP version, and a fleet with mixed architectures needs the extension set rebuilt per target. Nothing in the README describes a cross-compilation matrix or a way to produce one artefact per target from a single run.

The second case is a host that already has a good PHP. The static build pays off on minimal images and on machines where installing a package manager is not an option.

The third is the licensing surface. The MIT statement covers the project itself and then concedes that some extensions and dependencies originate elsewhere. Extensions are the part that actually ships inside your binary, so if the application is redistributed you need to check the terms of what you compiled in, not just the terms of the builder.

## Conclusion

Adopt StaticPHP if you need a PHP binary that runs on a machine with no PHP installed, and you are prepared to pin your extension list in craft.yml. Do not adopt it expecting the documented release process to be settled, because the README states the maintainers are preparing to release v3 with a project rename from static-php-cli to StaticPHP and the v3 branch is the default one you get. Verify first which PHP versions you actually need, since the supported range starts at 8.1 and 8.6 is listed as pre-release, and decide on an extension set deliberately because the two bundled sets differ by an order of magnitude in binary size.

## FAQ

### How do I install the spc build tool?

Download the binary for your platform with curl from dl.static-php.dev, for example https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64, then run chmod +x ./spc on macOS and Linux. The Windows download expects Windows 10 build 17063 or later and Visual Studio 2022 installed.

### How do I configure a StaticPHP build?

Create a craft.yml naming the php-version, a comma separated extensions list, the sapi entries and download options. The README supports PHP 8.1 through 8.5 with 8.6 listed as pre-release, and points to an online command generator as an alternative to writing the file by hand.

### What is the difference between the cli and micro SAPIs in StaticPHP?

The cli output is a standalone php interpreter you run as buildroot/bin/php -v. The micro output is a phpmicro self-extracting executable that combines the interpreter and your source into one file, produced with a command such as ./spc micro:combine a.php -O my-app.

### Why is the default branch called v3 and not main?

The README states the maintainers are preparing to release v3, which includes a project rename from static-php-cli to StaticPHP, and that this branch is the v3 branch while v2 lives elsewhere. A default clone therefore gives you the unreleased line.

### What sizes do the prebuilt StaticPHP binaries come in?

Two extension sets are offered per PHP version. The gigantic set includes as many extensions as possible at roughly 100 to 150MB, and the base set includes only a few extensions used by StaticPHP itself at roughly 10MB.

## Sources

- [crazywhalecc/static-php-cli on GitHub](https://github.com/crazywhalecc/static-php-cli)
- [License: MIT](https://github.com/crazywhalecc/static-php-cli/blob/v3/LICENSE)
- [Project website](https://static-php.dev)
- [README](https://github.com/crazywhalecc/static-php-cli/blob/v3/README.md)
- [Releases](https://github.com/crazywhalecc/static-php-cli/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/crazywhalecc-static-php-cli
