Stop waiting on PHPStan: Mago cuts static analysis time by 4x

Stop waiting on PHPStan: Mago cuts static analysis time by 4x

Jul 29, 2026

Mago is a static analysis toolchain for PHP written in Rust instead of PHP, and it's fast. In this video I cover installing Mago, linting your code, analyzing for bugs, and formatting your codebase, plus how it stacks up against PHPStan and Psalm on a real 134k-line project.

Timestamps and topics:

  • What Mago is and why Rust makes it fast
  • Installing Mago (curl script, Homebrew, Composer, Docker, WinGet)
  • Setting up mago.toml with mago init
  • Linting your code with mago lint and auto-fixing issues
  • Catching real bugs with mago analyze
  • Formatting your codebase with mago fmt
  • Speed comparison: Mago vs PHPStan and PHP_CodeSniffer
  • Gotchas to know before you adopt it

Mago site: https://mago.carthage.software/

I'm currently testing Mago as a "yes and" stage alongside PHPStan and Psalm rather than a full replacement, since some rules don't have equivalents yet. Let me know in the comments what static analysis tool you're using and how slow your CI is because of it.

If this video helped you, like it and share it with a developer on your team who's tired of waiting on builds.

PHP #StaticAnalysis #Rust #PHPStan #Mago #WebDevelopment

00:00 Introduction 01:22 What Is Mago? 01:50 Installing Mago 02:37 Setting Up Your Config 03:18 Linting Your Code 04:34 Analyzing for Bugs 05:26 Formatting Your Code 05:48 About That Speed 06:24 Fitting It Into Your Workflow 06:58 Gotchas 07:38 What You Need To Know 08:04 Outro

Links: Our Discord - https://discord.gg/aMTxunVx Buy our shirts - https://store.phparch.com/products/community-corner-podcast-t-shirt

Scott's Social Media: Website - https://scott.keck-warren.com/ Bluesky - https://bsky.app/profile/scottkeckwarren.bsky.social LinkedIn - https://www.linkedin.com/in/scott-keck-warren-91689810/ Mastodon - https://phpc.social/@scottkeckwarren

PHP Architect Social Media:

X: https://x.com/phparch Mastodon: https://phparch.social/@phparch Bluesky: https://bsky.app/profile/phparch.com Discord: https://discord.phparch.com

Subscribe to our magazine: https://www.phparch.com/subscribe/

Thanks to our Partners:

Displace - Infrastructure Management, Simplified https://displace.tech/

PHPScore - Put Your Technical Debt on Autopay https://phpscore.com/

CodeRabbit - Cut code review time & bugs in half instantly with CodeRabbit. https://www.coderabbit.ai/

Epidemic Sound https://www.epidemicsound.com/

Get PHP Architect Merch at our Store https://store.phparch.com/


Transcript

Scott Keck-Warren Scott Keck-Warren 0:05
I love static analysis tools to a degree that my coworkers find them annoying. Tools like PHPStan and Psalm catch bugs before they ever reach production, and once you get used to that safety net, it's almost impossible to imagine coding without it. But there is one thing about these tools that drives me a little crazy. they are slow. On a large codebase, a full analysis can take minutes, gigabytes of memory. I've actually had to split my analysis into chunks and run them in parallel just to get my build times back down to something that was reasonable. While that solution works, it's always felt like a hack to me. But today we're gonna be looking at a potentially better way. It's called Mago, and it's a static analysis tool for PHP written in Rust. rather than PHP, which makes it shockingly fast. We will cover how to install it, how to lint your code, how to analyze it for bugs, and how to format it. Hello developers and welcome to the PHP Architect channel. I'm your host, Scott Keck Warren, and today we are going to speed up your static analysis with a native Rust tool called Magot. If you're new here, we cover topics related to the PHP ecosystem, hit that subscribe button so you don't miss the next episode. Magot is a static analysis toolchain for PHP, but unlike other static analysis tools, it's not written in PHP. It's written in Rust. Because it is written in Rust, it compiles down to a single native binary. So you don't need the PHP runtime to run it and you don't need Compass to install it. But as a benefit, there's no bootstrapping overhead every time you kick it off. You just run the binary and it goes. So the quickest way to install Mago is with the official installer script. You might wanna check to see if it's changed, but here's what it was at the time that I recorded this video. That downloads the right binary for your operating system and drops it somewhere on your PATH. If you prefer a different approach, Mago is also available through the normal Composer install, but there is also Homebrew, Docker, and I think for the first time I've ever seen it, WinGet, so pick whatever fits your workflow best. On a Mac, brew install mago is about as painless as it gets. Once it's installed, confirm that it works. There's also a GitHub Action that will let you run Mago inside of your GitHub Actions, so feel free to use that. So the first step is to create a config file using the following command. This guides you through the process of creating a Mago configuration file at the root of your project. If you've used PHPStan or Psalm, think of these as the equivalent of your phpstan.neon or your XML file for Psalm. It's where you tell Mago which directories to scan, what PHP version to target, and how strict you want the rules to be. The format is clean and readable, so even if you've never seen it before, you will figure it out quickly. There are a ton of options, but try to keep it simple to start and then just add on more as you need them. The mago lint command checks your code against a set of rules covering correctness, consistency, and clarity. So let's say you have a function like the one on the screen. If you get— you'll get something like the following if you run the lint on it. Because this is safe to autofix, you can ask Mago to do it for you. And now our file has the correct strict types declaration at the top. You get more type safety and you didn't have to touch the file by hand. We'll have more after this word from our partners. As a programmer, you know that code reviews are critical, but are also time-consuming. CodeRabbit acts as your AI copilot, providing instant code review comments and potential impacts of every pull request. Beyond just flagging issues, CodeRabbit provides one-click fix solutions and lets you define custom code quality rules using AST grep patterns, catching subtle issues that traditional static analysis tools might miss. CodeRabbit reviews 1 million pull requests every week across 3 million repositories and is used by 100,000 open source projects. CodeRabbit is free for all open source project repos. Get started today at phpa.me/coderabbit. That's phpa.me/coderabbit. Well, linting is about style and clarity, and analysis is about catching actual bugs. I like this description that Mago has on their website. The analyzer builds a semantic model of your entire codebase. It knows what type functions will return, what properties classes have, and what can throw. It finds logical impossibilities like calling a method that does not exist on a type at hand. That is what Mago Analyze does. It hunts for problems like type mismatches, dead code, and logic that can't possibly work. Here is a quick example. This function promises to return an integer, but actually returns a string. Running the analyzer catches it right away. That is the kind of bug that would and will sit quietly until a customer hits it on the busiest day of the year. I know from experience. So Magot also allows us to force a formatting option on our code. The Magot format command applies deterministic consistent formatting to your whole codebase. Run it once and everyone on your team gets the exact same style with zero arguments about spacing or brace placement. In order to do what Magoo is doing with a single command, I have to run 2 other tools. And for some reason it's finding more issues than I have found in the other ones. My guess is that it's due to the differences in where the errors are categorized. In my test, it takes Magoo 3.4 seconds versus 13.9 seconds for the legacy tools on my 134,000-line side project. That's a large difference, especially given that I run these tools dozens of times a day, which will really add up. So I'm a huge fan of running tools like Magoo in my CI/CD pipeline and my pre-commit scripts. I'm currently testing it as a replacement for PHPStan and PHP CodeSniffer in my stack, and I'm excited to see the results coming back. But there are some gaps in its implementation I can't quite get around that more mature tools have. Right now I'm using it as my yes-and stage in my testing so I can get faster feedback, but it doesn't look like a direct replacement just yet. A few things to keep in mind. First, Mergo is still maturing. It is fast and capable, but not every single PHPStan and Psalm rule has an equivalent yet. So you may hit a check you are used to, used to, but is not there. I know I have. Secondly, the format reformats your entire codebase in place. Commit your work first. So if the formatting does something you did not expect, you can see exactly what changed in your diff and roll it back cleanly. Finally, remember that Mago reads its settings. From its own file. It does not look at your existing phpstan.neon or Psalm DEXML, so you will need to configure it fresh. As a brief recap, Mago is a static analysis toolchain for PHP written in Rust. Mago lint checks for correctness, consistency, and clarity. Analyze catches type errors and dead code paths. Format handles formatting. It's not as mature as other tools in the ecosystem, but hopefully this will change soon. So I have to ask, what static analysis tools are you using right now and how slow is your CI because of it? Let me know in the comments below, because I am curious whether Magot could save you the same headaches it has saved me. And if this video helped you out, please give it a like and a share. This is Scott Keck Warren for the PHP Architect channel signing off and reminding you to keep watching, keep coding, and keep reading.