I've just tried to apply it to a medium-sized project, and it spitted tens of thousands of errors where phpstan and psalm don't see any. At first glance, it's because Mago does not parse phpdoc. In its current beta state, Mago is meaningless for all the big PHP projects, which are its main target.
Mago might succeed, but I wouldn't bet on it. Its main selling point is that it promises to be faster than the usual static analysers-linters (phpstan and psalm). But if it does not reach feature parity with them, the speed gain probably won't convince PHP projects to drop the standard tools. Since phpstan and Co keep evolving, keeping feature parity will require constant work. And PHP is more niche than Python or JS, so contributors mastering Rust and PHP will be fewer, compared to phpstan/psalm which are written in PHP.
I initially thought this was a PHP implementation in Rust.... but it's not
Will Mago implement a PHP runtime?
Absolutely not. The PHP runtime is incredibly complex. Major efforts by large companies (e.g., Facebook's HHVM, VK's KPHP) have struggled to reach full parity with Zend Engine. Achieving this as a smaller project is infeasible and would lead to community fragmentation. We are focused on tooling, not runtimes.
Not really? .NET has a "Common Language Runtime", which you can think of as analogous to the Java VM or to Beam.
A transpiler might read PHP and spit out C, or Java or some other existing programming language, spitting out the code for a virtual machine doesn't make you a transpiler unless you're going to argue that all compilers are just transpilers, it's like one of those "Actually goats are fish" arguments. OK, but now the word "fish" is useless so why go to this bother ?
Seen this around quite abit over the past few days. I wish the github landing page/readme would actually substansiate why this is better beyond it being written in rust which seems to be the main argument for the tool right now. I make my money from PHP, I preffer stability.
There are two deep capabilities that make Rust, Rust:
1. Banning shared, mutable data. You can't change data that other code might be reading. This is a huge win for threading and multiple CPUs, but it's a dramatic departure from other popular languages.
2. Knowing how data is laid out in memory. This is classic "systems programming" stuff, and it's also present in C, C++, Zed, etc. This usually goes along with making memory allocation visible (though not always in C++). This is a big win for performance.
If you wanted to build a "scripting language" version of Rust, you could probably lose (2). Languages like Haskell are even stricter than Rust, but they hide the details of memory layout. But then you need to decide whether to keep or lose (1). If you keep it, your language will have good threading, but users will need to think about ownership and borrowing. If you lose (1), then your language won't feel very much like Rust.
It would be an interesting intellectual exercise! But actually turning it into a popular scripting language would probably require the same luck and the same 10 years of work that most successful languages need to get real traction.
>If you wanted to build a "scripting language" version of Rust, you could probably lose (2).
Not really no. I work on an interpreted language runtime in Rust professionally and it's still a huge help even if you're still eating perf pain on the interpreted language itself for the same reasons everyone else does. There's more benefit to Rust than you're really capturing here but that's to be expected, it's a short comment.
Here are some other things we get from using Rust for interpreted languages:
- The `unsafe` parts are relatively limited in scope and we have much better and more automated verification tools for `unsafe`, especially WRT undefined behavior
- Being able to make large architectural changes and work through them mechanically/quickly because of the type-checking and borrow-checking is absurdly powerful for any project, all the more so in this context.
- The library ecosystem for Rust has been fantastic for all kinds of projects but it's especially good for PL runtimes.
- LLMs are a lot better at Rust than other programming languages. I have a lot of experience using LLMs in a variety of domains and programming languages and it's far better at Rust than anything else that's expressly about programming. Arguably it's even better at Terraform and Ansible but I consider that a different category. Controversial point maybe but I get tremendous yield out of it.
- It's not just that Rust is fast. It is on par w/ C/C++ all else being equal. What's significant here is that it is a _lot_ quicker/easier to hit the 80/20 perf targets as well as the bleeding edge performance frontier in a Rust application than it is in C and C++. A lot of C and C++ projects leave performance on the table either because it's too hard to make the ownership model human-maintainable/correct or because it would be too much work to refactor for the hoped-for perf yield. Not as much an issue in Rust. You can gin up hypothetical perf improvements in Rust with gpt-5 lickety-split and the types/borrowck will catch most problems while the agent is iterating.
Shared, mutable data aren't really banned, we use it strategically in our Rust interpreter, it's just not default-permitted. Aliasing is precisely the distinction between a safe reference and an unsafe pointer in Rust. Aliasing a mutable pointer in Rust isn't UB, it's just `unsafe`. OTOH, aliasing a mutable reference _is_ UB and not allowed in Rust. Miri will catch you if you do this.
On top of all that, you have some nice kit for experimenting with JIT like Cranelift.
To be fair it is pretty significant. Especially uv. I don't know anything about PHP's existing toolchain but I do know that Python's is a horrifying mess, and uv basically fixes it.
It's a small thing in the Rust community but it's pretty huge in the world simply because there are so many Python developers (and also because of the extreme magnitude of improvement). Probably wouldn't have happened without Rust.
Thanks to Rust, there are heaps of next generation CLI utilities that have come onto the scene in the past decade. Cross platform by default, UTF8 aware, more likely to be multi-threaded, simple distribution, and most importantly - improving on some unfortunate legacy API decisions.
Ripgrep, fd, tokei, Just, zellij, uv, and so forth. Porting languages has given the opportunity to remove some of the cruft decided on a whim in the 70s. None of these are world changing, but they do make life easier than the originals.
I don't think it's strange at all to call this Rust's biggest win. Adopting Rust-based tooling has sped up development and lowered CI costs for millions of JavaScript and Python developers. I can't think of anything else Rust has been used for which has had a larger direct impact on people's everyday lives.
Not the biggest, but definitely the most visible to people who aren’t dialled into Rust news. For example, many people use Android but they wouldn’t know or need to know that their Bluetooth stack is written in Rust.
Whereas anyone who uses Python would have heard of uv and why it’s much faster than other tools.
All the language tools that are being displaced by newer rust replacements were definitely not written in C/C++. They were/are written in the host language (js/java/python/php/ruby).
Which is striking right? Nobody went "Oh, I should write C++ to speed up my Python tool", or if they did we don't know about it because they're still trying to understand the six thousand lines of template spaghetti their compiler spat out due to a typo in one line of their code.
It is very cool that this exists, but the PHP community lacks the resources to see a non-PHP tool thrive.
Tools like Sorbet (C typechecker for Ruby) or tsgo (Go-based successor to TypeScript's typechecker) are only viable because big profitable companies can back them up with engineering hours.
True but TypeScript and Sorbet are magnitudes above linting and formatting PHP, in terms of challenge size.
TypeScript is a very complex language with a huge mission. From the same creator of C#.
Sorbet is trying to tame a dynamically typed language which supports monkey patching. Stripe can get away with it because they have close to infinite money and a large Ruby codebase.
Meanwhile PHP is stable and typed. Parsing AST, linting and formatting are trivial in comparison to the examples you cited. Their package manager, composer, is also boring a stable, in a good way. Prime target for a second pass if need be.
I would posit that you do not know what you’re talking about. Mayo is also a static analysis tool that does typechecking. It incorporates and is heavily influenced by code I wrote.
All of this already exists and each separate product is actively developed, keeping up with all of the changes in PHP. This toolset looks too ambitious.
Astral did something similar for the Python ecosystem (Rust-inspired tooling built in Rust, replacing a lot of pre-existing - bad - tooling) & the impact has been revolutionary. Python had some of the worst tooling of any popular language & now has some of the best.
Composer is one of the best package managers in any language ecosystem but beyond that, other PHP tooling, while technically well maintained, aren't particularly great at what they do. It's an ideal starting point for positive disruption.
2G of ram at build is not that outrageous, however yes, with composer2 (released like 7 years ago?) it uses less ram.
Also the frameworks got less bloated and more modular
The README is quite ahead of reality: it never mention that Mago is still beta software. A roadmap to a first release was created 5 days ago, https://github.com/carthage-software/mago/issues/405.
I've just tried to apply it to a medium-sized project, and it spitted tens of thousands of errors where phpstan and psalm don't see any. At first glance, it's because Mago does not parse phpdoc. In its current beta state, Mago is meaningless for all the big PHP projects, which are its main target.
Mago might succeed, but I wouldn't bet on it. Its main selling point is that it promises to be faster than the usual static analysers-linters (phpstan and psalm). But if it does not reach feature parity with them, the speed gain probably won't convince PHP projects to drop the standard tools. Since phpstan and Co keep evolving, keeping feature parity will require constant work. And PHP is more niche than Python or JS, so contributors mastering Rust and PHP will be fewer, compared to phpstan/psalm which are written in PHP.
I initially thought this was a PHP implementation in Rust.... but it's not
Will Mago implement a PHP runtime?
Absolutely not. The PHP runtime is incredibly complex. Major efforts by large companies (e.g., Facebook's HHVM, VK's KPHP) have struggled to reach full parity with Zend Engine. Achieving this as a smaller project is infeasible and would lead to community fragmentation. We are focused on tooling, not runtimes.
https://mago.carthage.software/faq
> The PHP runtime is incredibly complex
Say this to the team behind Ladybird browser: https://awesomekling.substack.com/p/how-were-building-a-brow...
They have the benefit of a project leader with many years of browser implementation experience AND much lower performance goals.
(Items 5 and 3 on the list in the linked page.)
80/20, also they're not implementing JIT and such because of complexity.
https://www.peachpie.io compiles PHP to .NET.
Isn't this more transpiling than compiling?
Not really? .NET has a "Common Language Runtime", which you can think of as analogous to the Java VM or to Beam.
A transpiler might read PHP and spit out C, or Java or some other existing programming language, spitting out the code for a virtual machine doesn't make you a transpiler unless you're going to argue that all compilers are just transpilers, it's like one of those "Actually goats are fish" arguments. OK, but now the word "fish" is useless so why go to this bother ?
Seen this around quite abit over the past few days. I wish the github landing page/readme would actually substansiate why this is better beyond it being written in rust which seems to be the main argument for the tool right now. I make my money from PHP, I preffer stability.
seems rust's biggest win was improving other languages toolchains and bringing increased productivity to those languages.
Not a bad win so far, right? One hand washes the other and both wash the face.
I am waiting for someone to build a modern scripting language in Rust that has the popularity and rich tooling and capabilities of Rust as a result.
There are two deep capabilities that make Rust, Rust:
1. Banning shared, mutable data. You can't change data that other code might be reading. This is a huge win for threading and multiple CPUs, but it's a dramatic departure from other popular languages.
2. Knowing how data is laid out in memory. This is classic "systems programming" stuff, and it's also present in C, C++, Zed, etc. This usually goes along with making memory allocation visible (though not always in C++). This is a big win for performance.
If you wanted to build a "scripting language" version of Rust, you could probably lose (2). Languages like Haskell are even stricter than Rust, but they hide the details of memory layout. But then you need to decide whether to keep or lose (1). If you keep it, your language will have good threading, but users will need to think about ownership and borrowing. If you lose (1), then your language won't feel very much like Rust.
It would be an interesting intellectual exercise! But actually turning it into a popular scripting language would probably require the same luck and the same 10 years of work that most successful languages need to get real traction.
>If you wanted to build a "scripting language" version of Rust, you could probably lose (2).
Not really no. I work on an interpreted language runtime in Rust professionally and it's still a huge help even if you're still eating perf pain on the interpreted language itself for the same reasons everyone else does. There's more benefit to Rust than you're really capturing here but that's to be expected, it's a short comment.
Here are some other things we get from using Rust for interpreted languages:
- The `unsafe` parts are relatively limited in scope and we have much better and more automated verification tools for `unsafe`, especially WRT undefined behavior
- Being able to make large architectural changes and work through them mechanically/quickly because of the type-checking and borrow-checking is absurdly powerful for any project, all the more so in this context.
- The library ecosystem for Rust has been fantastic for all kinds of projects but it's especially good for PL runtimes.
- LLMs are a lot better at Rust than other programming languages. I have a lot of experience using LLMs in a variety of domains and programming languages and it's far better at Rust than anything else that's expressly about programming. Arguably it's even better at Terraform and Ansible but I consider that a different category. Controversial point maybe but I get tremendous yield out of it.
- It's not just that Rust is fast. It is on par w/ C/C++ all else being equal. What's significant here is that it is a _lot_ quicker/easier to hit the 80/20 perf targets as well as the bleeding edge performance frontier in a Rust application than it is in C and C++. A lot of C and C++ projects leave performance on the table either because it's too hard to make the ownership model human-maintainable/correct or because it would be too much work to refactor for the hoped-for perf yield. Not as much an issue in Rust. You can gin up hypothetical perf improvements in Rust with gpt-5 lickety-split and the types/borrowck will catch most problems while the agent is iterating.
Shared, mutable data aren't really banned, we use it strategically in our Rust interpreter, it's just not default-permitted. Aliasing is precisely the distinction between a safe reference and an unsafe pointer in Rust. Aliasing a mutable pointer in Rust isn't UB, it's just `unsafe`. OTOH, aliasing a mutable reference _is_ UB and not allowed in Rust. Miri will catch you if you do this.
On top of all that, you have some nice kit for experimenting with JIT like Cranelift.
Like Gleam?
I was thinking similar but more like a Python or Lua but all in Rust.
It doesn't have imperative constructs I think. So half of developers or more are out front the get go.
Do you really think that this is Rust's biggest win or are you just joking/trolling?
To be fair it is pretty significant. Especially uv. I don't know anything about PHP's existing toolchain but I do know that Python's is a horrifying mess, and uv basically fixes it.
It's a small thing in the Rust community but it's pretty huge in the world simply because there are so many Python developers (and also because of the extreme magnitude of improvement). Probably wouldn't have happened without Rust.
Thanks to Rust, there are heaps of next generation CLI utilities that have come onto the scene in the past decade. Cross platform by default, UTF8 aware, more likely to be multi-threaded, simple distribution, and most importantly - improving on some unfortunate legacy API decisions.
Ripgrep, fd, tokei, Just, zellij, uv, and so forth. Porting languages has given the opportunity to remove some of the cruft decided on a whim in the 70s. None of these are world changing, but they do make life easier than the originals.
I don't think it's strange at all to call this Rust's biggest win. Adopting Rust-based tooling has sped up development and lowered CI costs for millions of JavaScript and Python developers. I can't think of anything else Rust has been used for which has had a larger direct impact on people's everyday lives.
Not the biggest, but definitely the most visible to people who aren’t dialled into Rust news. For example, many people use Android but they wouldn’t know or need to know that their Bluetooth stack is written in Rust.
Whereas anyone who uses Python would have heard of uv and why it’s much faster than other tools.
You're wrong because it's also incrementally replacing individual, high-risk components in Windows and Linux.
But even if you're not wrong, a major mission of Rust was to be a safer C/C++, and language tooling used to be dominated by those languages.
All the language tools that are being displaced by newer rust replacements were definitely not written in C/C++. They were/are written in the host language (js/java/python/php/ruby).
Which is striking right? Nobody went "Oh, I should write C++ to speed up my Python tool", or if they did we don't know about it because they're still trying to understand the six thousand lines of template spaghetti their compiler spat out due to a typo in one line of their code.
So I guess this is `uv`, but for PHP?
If it has remotely the same success, that would be a huge win for the ecosystem!
It's more like `ruff` for PHP.
No its different, php already has a good package manager, this is about formatting, linting and type checking
It is very cool that this exists, but the PHP community lacks the resources to see a non-PHP tool thrive.
Tools like Sorbet (C typechecker for Ruby) or tsgo (Go-based successor to TypeScript's typechecker) are only viable because big profitable companies can back them up with engineering hours.
> PHP community lacks the resources to see a non-PHP tool thrive.
Why do you think so?
The PHP Foundation has raised over 2 million USD in contribution and has over 500K in their balance currently according to:
https://opencollective.com/phpfoundation
PHP has some well funded groups using it like Wordpress, Wikipedia, Laravel to name a few.
And recently the PHP Foundation started officially sponsoring a Go project, FrankenPHP.
https://thephp.foundation/blog/2025/05/15/frankenphp/
So PHP looks like a friendly and well supported community to foster tooling made in other languages.
> The PHP Foundation has raised over 2 million USD in contribution and has over 500K in their balance
This is great, but it is still dwarfed by the amount Microsoft has spent on TypeScript and also by the amount Stripe has spent on Sorbet.
500k is roughly comparable to the amount my previous company spent (grudgingly) to keep me employed and working on PHP tooling for a couple of years.
True but TypeScript and Sorbet are magnitudes above linting and formatting PHP, in terms of challenge size.
TypeScript is a very complex language with a huge mission. From the same creator of C#.
Sorbet is trying to tame a dynamically typed language which supports monkey patching. Stripe can get away with it because they have close to infinite money and a large Ruby codebase.
Meanwhile PHP is stable and typed. Parsing AST, linting and formatting are trivial in comparison to the examples you cited. Their package manager, composer, is also boring a stable, in a good way. Prime target for a second pass if need be.
I would posit that you do not know what you’re talking about. Mayo is also a static analysis tool that does typechecking. It incorporates and is heavily influenced by code I wrote.
Interesting. Do you have any thoughts to share along the same lines about FrankenPHP?
It's cool that it's part of the PHP foundation, but it's not all that complex.
FrankenPHP has >100 contributors, including 3 very frequent ones, and about 17k lines of Go.
Mago has 11 contributors, with just 1 very frequent one, and about 135k lines of Rust.
But what does it do?
How many hours and dollars get wasted on reimplementing the same basic concepts over and over for this or that language runtime?
Love seeing some Tunisian representation here ! Kudos on the project !
All of this already exists and each separate product is actively developed, keeping up with all of the changes in PHP. This toolset looks too ambitious.
Astral did something similar for the Python ecosystem (Rust-inspired tooling built in Rust, replacing a lot of pre-existing - bad - tooling) & the impact has been revolutionary. Python had some of the worst tooling of any popular language & now has some of the best.
Composer is one of the best package managers in any language ecosystem but beyond that, other PHP tooling, while technically well maintained, aren't particularly great at what they do. It's an ideal starting point for positive disruption.
I really wasn't using Composer for last couple of years. Did it already stopped eating 2GB RAM for any project that use framework like Laravel?
Composer is a good tool, but it's resource usage was abysmal.
2G of ram at build is not that outrageous, however yes, with composer2 (released like 7 years ago?) it uses less ram. Also the frameworks got less bloated and more modular
Yes it did. Composer 2 is way lighter and faster