Mago — the Rust-powered PHP linter and formatter that sets up in 5 minutes

Mago — the Rust-powered PHP linter and formatter that sets up in 5 minutes

Mago (v1.29.0) is a single Rust binary that replaces PHP-CS-Fixer, PHPStan, and PHP_CodeSniffer for PHP projects — formatting WordPress (7M lines) in 0.43 seconds vs PHP-CS-Fixer's 25.3 seconds. The official VS Code extension `Clearlyip.mago-vscode-extension` v0.9.5 connects via a persistent LSP server rather than spawning a CLI process on each save, enabling real-time diagnostics and format-on-save. Covers 4-step setup, before/after formatting demo, and honest caveats on the unstable LSP preview, analyzer false positives, and the lack of a PHP extension ecosystem.

VS Code / JetBrains Plugin Pick
June 2, 2026 · 1:29 AM
1 subscriptions · 15 items
PHP projects typically need three separate tools wired together: PHP-CS-Fixer for formatting, PHPStan or Psalm for static analysis, and a linter like PHP_CodeSniffer. Each runs as a PHP process, each needs Composer, and each hits the interpreter cold on every save. On a codebase the size of WordPress — about 7 million lines — PHP-CS-Fixer takes 25.3 seconds to format and PHPStan takes 55.9 seconds to analyze. 1
Mago (Carthage Software, carthage-software/mago, v1.29.0) ships all three as a single Rust binary with no PHP runtime dependency at all. On the same WordPress corpus, it formats in 0.43 seconds and analyzes in 1.46 seconds. 1 The VS Code extension (Clearlyip.mago-vscode-extension v0.9.5) connects via Language Server Protocol — a persistent server process rather than spawning the binary on every keystroke — giving you real-time diagnostics, format-on-save, hover, completions, and inlay hints. 2

Why the LSP approach matters

Several unofficial Mago extensions exist on the VS Code Marketplace. The key difference with the official one is architectural: unofficial extensions spawn a new Mago CLI process for every format-on-save trigger or diagnostic request. The Clearlyip extension instead keeps one persistent language server running and communicates over LSP. 3
In practice that means lower latency on every save, incremental workspace state, and richer editor integration — code lenses, inlay hints, and hover tooltips that CLI-based wrappers can't provide. The extension also watches mago.toml and auto-restarts the server when you modify config, so changes take effect without touching VS Code.
If another Mago extension is already installed (e.g. Michael4d45.mago-vscode or kgz.mago-unofficial), the Clearlyip extension detects it and warns you about duplicate diagnostics. Disable the others before enabling this one.

Five-minute setup

Requirements: VS Code ≥ 1.95.0, PHP project with Composer, PHP 8.1+.

1. Install the LSP-enabled binary

The Composer route installs a pre-built native binary — no compilation needed:
composer require --dev clearlyip/mago-lsp
Loading content card…
This places the binary at vendor/bin/mago-lsp. The VS Code extension checks that path first, then falls back to mago on PATH. 4

2. Scaffold your config

vendor/bin/mago-lsp init
The interactive prompt asks for your PHP version and source paths, then writes a mago.toml to your project root. 5

3. Install the VS Code extension

Search Mago LSP in the Extensions panel (publisher: Clearlyip), or install from the terminal:
code --install-extension Clearlyip.mago-vscode-extension

4. Enable format-on-save

Add these two lines to .vscode/settings.json:
{
  "[php]": {
    "editor.defaultFormatter": "Clearlyip.mago-vscode-extension",
    "editor.formatOnSave": true
  }
}
That's the full setup. Open any PHP file and you should see diagnostics appear in the Problems panel within a few seconds.

The .mago.toml config

A minimal production config looks like this:
#:schema https://mago.carthage.software/1.29.0/schema.json

version = "1"
php-version = "8.3"

[source]
paths    = ["src", "tests"]
includes = ["vendor"]
excludes = ["vendor/bin"]

[formatter]
print-width    = 120
single-quote   = true
trailing-comma = true
The #:schema comment gives you autocomplete in Taplo (the TOML LSP). 6
The formatter ships four presets under [formatter] preset = "...": default (PER-CS — PHP Evolving Recommendation Coding Standard), psr-12, laravel (mirrors Laravel Pint), and drupal. You can combine a preset with individual overrides — Mago applies the preset first, then the explicit options on top. 7
Before (typical legacy PHP file):
<?php
use App\Models\{ User, Post };
use App\Services\AuthService;

class UserController {
    function __construct(private readonly AuthService $auth) {}

function index(): array {
        return [
            "users" => User::all(),
            "posts" => Post::all()
        ];
    }
}
?>
After (Mago defaults, PER-CS):
<?php

use App\Models\Post;
use App\Models\User;
use App\Services\AuthService;

class UserController
{
    public function __construct(private readonly AuthService $auth) {}

public function index(): array
    {
        return [
            'users' => User::all(),
            'posts' => Post::all(),
        ];
    }
}
Mago expands grouped use statements into individual imports, alphabetizes them, converts double-quoted strings to single quotes, adds trailing commas to multi-line arrays, removes the closing ?> tag, and puts <?php on its own line with a blank line after — all without touching the AST. 7
Mago LSP VS Code extension banner
The Mago LSP extension header from its GitHub repository (MIT license). 3

What to know before switching

Mago's formatter and linter are production-stable. The Tempest framework team has run Mago's formatter and linter in production for about a year. 8 The static analyzer is a different story.
The LSP is an unstable preview. The marketplace listing carries an explicit warning: "The LSP implementation, advertised capabilities, CLI flags, and wire protocol may change without notice before Mago 2.0." 2 The official plan is to ship the LSP feature-complete with the 2.0.0 release; the Composer package and the VS Code extension exist ahead of that as a preview.
The static analyzer produces many false positives on real projects. An independent test on a 3,000-file codebase found Mago v1.0.2 reporting 1,000+ errors while PHPStan at max level reported zero. 9 Tempest framework creator Brent Roose (brendt_gd) confirmed in early 2026 that the static analyzer "wasn't good enough yet: many false positives." 8 You can disable the analyzer entirely in the extension via "mago.noAnalyzer": true and use only the formatter and linter.
No PHPStan or Psalm extension ecosystem. Projects that rely on framework-specific PHPStan packages (Larastan, Symfony PHPStan Extension, Magento rules) will see false positives where Mago lacks the type stubs those packages provide. Future custom rules will require Rust (compiled to WASM) — not PHP. 10
No doc comment formatting. Mago's deterministic formatter — like gofmt or Prettier — parses to AST and reprints. It does not yet reformat PHPDoc blocks, which is a blocker for Drupal coding-standard compliance. 11
The practical move for most projects today: use Mago as your formatter and linter (stable, fast), keep PHPStan for static analysis, and revisit the analyzer when Mago 2.0 ships.

Install

Plugin: Mago LSP · Extension ID: Clearlyip.mago-vscode-extension · Version: v0.9.5 (extension), v1.29.0 (Mago binary, released 2026-05-23) · IDE: VS Code ≥ 1.95.0 · Language: PHP (≥ 8.1) · Use case: Linting, formatting, static analysis (LSP) · Publisher: Clearlyip · GitHub stars: 3.2k (Mago core), JetBrains is a financial sponsor 12 · Packagist installs: 965k 13
Loading content card…
Cover image: official Mago banner from mago.carthage.software

Add more perspectives or context around this Post.

  • Sign in to comment.