Unicorn Benefits of Rust/Go Tooling in PHP

We've established that we, PHP devs, can benefit from tooling written in a language we don't understand as well as we do PHP. How exactly?

Zero Dependencies

It's best to use the latest dependencies, we all know it, until we try it in a real project:

  • I wanted to try PHPUnit 13, but Paratest only supported PHPUnit 12.
  • I wanted to try Pest Tia, but it required PHPUnit 13.
  • PHPUnit 13 needs sebastian/diff 9.0, but one of our packages only allowed 7.0. When I checked the latest version of that package, it supported as high as 8.0.
  • All require PHP 8.4+.
  • I wanted to try PHPStan Turbo, but it requires PHP 8.3 and higher.

The majority of profitable private PHP projects are not open sourced and are not on the latest PHP version. Ironically, exactly these projects need dev-tools the most to get to the latest PHP/fw versions.

  • Rector requires php-parser and PHP 7.4+
  • PHPStan requires php-parser and PHP 7.4+
  • ECS requires PHP 7.2+ and 0 deps
  • Mago has this potential, as a tool written in Rust. But for some reason, it requires PHP 8.1+, which makes it even less usable than the tools above.

There is also a tradition, that new features require a newer PHP version and newer dependencies. Imagine PHPStan, which got 3x faster this year, would work on any PHP version. 100 % of my clients would benefit from it.


Expect the Best as Minimum

Instead, we should expect and get the following experience:

composer require some-cool/go-tool

# always installs, always runs

# 0 PHP version blockers, 0 conflicts with other tools/packages

The latest tool, with the latest features, with the best speed optimization.

The tool should be able:

  • to pick up PHP version of our project from composer.json
  • use a proper parser version to understand it
  • not to autoload our code, but use static reflection (= parse /vendor)

(We can mimic this by scoped downgrade, but it has its design flaws and speed penalty for older PHP versions.)

So Agents won't fry your Laptop

Why do we need a tool that runs in <1s where the next best runs 20-60 s?

During summer I was using Rector and PHPStan a lot. After every code change, I ran the saint trio - tests, static analysis and Rector. Naturally, agents took on the same behavior pattern.

Adding a custom PHPStan/Rector here and there, and full re-run happens without cache.

My CPU cores were through the roof, keyboard close to boiling point. In that very moment, the tooling became a bottleneck. I was penalized for using tailored AST tooling. My laptop battery used to last 3 hours in Spring 2026, now in Summer 2026, it ran out in under 50 mins.

I had to watch what I was typing.


This is my CPU usage a few mins ago on one project, running on PHP 8.4.

I ran Rector, went to the toilet, came back... and it was still running. How is that possible? Well, one agent was splitting a PR into 3 smaller ones and running full CI on it locally - (PHPStan + Rector + ECS in parallel) * 4 = 12 processes that each ask for 24 cores.

A laptop with 288 CPU cores might do the job. Instead, everything starts lagging.

Agents will pick faster tools. More so in time

Agents are being punished for using the tools we made for them - not on value alone, but on the very preference we embodied in them:

Would you use PHPStorm or would you pick Zed/Terminal?

A tool run must be as fast as the rest of our tooling - git commit, git checkout, sed, ls, opening a browser tab - in parallel, without blocking, in a couple of ms. If these took 30 seconds, would you use them daily? If one takes 30 s and another takes 1 s, which do you pick?

It's about choice.

We should be able to run 5 agents, each running all CI checks locally - Rector, ECS, PHPStan, even PHPUnit in parallel - and 80 % of our cores should still be free. Locally, remotely, on VPS, on a smartphone, as an Orb, AMP, MCP... anywhere. That's where we're heading.


Mago leading path not taken.

Comment
by u/azjezz from discussion
in PHP

Go/Rust not for websites, but for Speed

PHP is the best language for websites and REST API projects... that I know (of). Not so much for code changes and analysis. But Go/Rust on the other hand, are the best for code changes. Code changes of another language too.

We can teach Go/Rust to read PHP code, parse it into tokens, run a coding standard tool, parse it to abstract syntax tree, so we can run static analysis and type-aware code transformations. If you follow me on X, you already know about one such tool we've used in PHP for 9 years.

  • Where ECS runs 10 s, we should see 0.5
  • Where PHPStan runs 20 s, we should see <1s.
  • Where Rector runs 40 s, we should see <1s.
  • Where PHPUnit runs 60 s, we should see <1s.

For us, for agents, for watts, for creativity.

Empower new Wave of Creativity

Imagine we already have such a tooling. Our CI runs 5 seconds instead of 15 minutes. How would that affect our workflows?

How many experiments can we do in 10 seconds? How about agents, how many iterations can it do in a 1-minute session for the same amount of tokens? Instead of making us happy by picking the best of 3 options in 30 seconds, they could actually run all the simulations in parallel for the same amount of tokens and time.

Such a codebase would lead to order of magnitude scale next year.

Any feature you dream of is now possible.


But the speed is not the goal, not means to an end.
It's an enabler of greater ideas.

Dream big, then Code it

Long story short, I've taken over a PHP parser in Go, added PHP 8 support and a couple more changes. Then I've tried to implement ~100 Rector rules and run it. It took under 1 s!

What now with all that time? We can add a couple cool features that make our lives as maintainers easier. Like:

  • run all the sets (dead-code, type-coverage, code-quality, PHP...)
  • use 1 PR = 1 set
  • use 1 rule = 1 commit
  • open them all in parallel
  • run CI checks on those X branches

We're not writing instructions to an agent here. That's a real task the software tool handles. With Rector/PHPStan in current world, this might take something between 10-15 minutes with all cores to max.

With Reco, a Golang tool I built locally, this took 30 seconds. That includes:

  • sort 100 rules by group
  • running 100 rules in series, to be able to build commit after commit
  • open a PR once a group is done, if any changes were made
  • checkout new branch of the main for fresh work
  • use gh api to make PRs and open them in the browser

30 seconds. That's the most complex task we can do... or is it?

Full Context, Available Instantly

But we can do more, a static analysis based on full project context. Currently, PHPStan does one file-at-a-time analysis. It doesn't see the full project, only the current file's parents and family tree. It has collectors, that try to resolve this, but at great performance cost and complex setup.

With full context we could make every class final, because it could be:

  • extended
  • mocked
  • hacked modified by reflection

Same way we cannot make every class readonly, because it could be:

  • modified by reflection
  • modified by closure
  • mocked in tests to change state

What if we had full context available the moment we run the tool?

  • we know all mocked classes, method and properties
  • we know full family tree of project, children, parent, interfaces, trait usage
  • we know all the classes, properties and methods hacked by reflection

I made such a rule to finalize using php-parser, it takes ages (30-40 s) to find only the family tree. Excluding the reflection and mocks.

In Reco (Go or Rust), we can run this in <1 s. That's insane. If you'd told me in May 2026 this is possible, I would be asking: why has nobody built this before? I want this.


How do we build such a tool with zero lang knowledge? What are the blind paths we should avoid? How do "cool & amazing" Twitter stories differ from real maintenance of such a tool? How does one do a migration of PHP tool to Go/Rust?

Stay tuned for next post.


Happy coding!