NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #1188 most downloaded on Packagist
Mago is a toolchain for PHP that aims to provide a set of tools to help developers write better code.
Last release today
08 Oct 2026
Ships on a steady schedule
a new release about every 2 weeks
Some releases are documented
notes for 22 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
185 releases · first in 2025
Mago 1.53.0 improves analysis performance, file loading, name handling, and reporting, and fixes formatting of yield , direct new calls, and nested lo
Mago 1.53.0 improves analysis performance, file loading, name handling, and reporting, and fixes formatting of yield, direct new calls, and nested logical groups.
Note
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
yield and yield from behavior in binary expressions. (#2432, d374fef)new calls: omits redundant parentheses on PHP 8.4+, while honoring formatter settings. (#2430, cb4356f)No protocol changes in this release.
Thank you to everyone who contributed to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.52.0...1.53.0
One column per month.
Mago 1.52.0 makes analysis faster from file loading through reporting, adds rdkafka stubs, and fixes constant visibility, nullsafe loop types, magic-m
Mago 1.52.0 makes analysis faster from file loading through reporting, adds rdkafka stubs, and fixes constant visibility, nullsafe loop types, magic-method names, and built-in signatures.
Note
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
??. (#2428, ab12076)'refresh_token' while still checking names. (#2028, #2420, 4a9913b)null, in Ds\Map::get() and remove(). (#2425, cbb33fe)No protocol changes in this release.
Thank you to everyone who contributed to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.51.2...1.52.0
Mago 1.51.2 fixes macOS and FreeBSD release builds. There are no analyzer, linter, formatter, or guard changes.
Mago 1.51.2 fixes macOS and FreeBSD release builds. There are no analyzer, linter, formatter, or guard changes.
Note
Does your company use Mago? Please consider sponsoring its development so we can keep fixing bugs and shipping releases.
Sponsor Mago ❤️
libc to 0.2.189 to fix the missing NOTE_PCTRLMASK error in mio. (e1c4ab6)No protocol changes in this release.
Full Changelog: 1.51.1...1.51.2
Mago 1.51.1 fixes false positives in mixed-condition analysis, restores optional built-in arguments, and corrects PSR-12 declarations, parameter align
Mago 1.51.1 fixes false positives in mixed-condition analysis, restores optional built-in arguments, and corrects PSR-12 declarations, parameter alignment, and method-chain formatting.
Note
Does your company use Mago? Please consider sponsoring its development. We need funding to keep improving Mago, fixing bugs, and shipping releases.
Sponsor Mago ❤️
= in declare statements. (#2416, 6fcc28d)... and & attached to parameter names. (#2182, #2417, 0dea4da)array_find_key: infers null for empty arrays and keeps input key types otherwise. (#2389, df7b3c7)No protocol changes in this release.
Thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.51.0...1.51.1
Mago 1.51.0 adds Swoole stubs and improves type analysis, with fixes for static locals, loop types, boolean guards, lint suggestions, and formatting.
Mago 1.51.0 adds Swoole stubs and improves type analysis, with fixes for static locals, loop types, boolean guards, lint suggestions, and formatting.
Note
Does your company use Mago? Please consider sponsoring its development. We need funding to keep improving Mago, fixing bugs, and shipping releases.
Sponsor Mago ❤️
__invoke results marked #[NoDiscard] or @must-use. (#2400, f01b94e)finally blocks. (#2410, 71764f0)if and changes in one branch. (#2411, 0d0224d)list(). (#2407, #2408, a11d5e3, 5d804d7)hook_* names in *.api.php unchanged with Drupal integration. (#2390, #2391, 335d8a7)?> after method chains with a semicolon on its own line. (#2393, 17cc593)extends to the schema. (#2354, 8556e0e)str_increment: marks its return type as non-empty-string. (452721b)number or null, using the schema. (#2398, 7ceff94)No protocol changes in this release.
A huge thank you to everyone who contributed to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.50.0...1.51.0
Mago 1.50.0 adds mago fix to apply fixes across all four tools until no changes remain, alongside safer imports, better type analysis, and more flexib
Mago 1.50.0 adds mago fix to apply fixes across all four tools until no changes remain, alongside safer imports, better type analysis, and more flexible pragmas and guard patterns.
mago fix: runs guard, analyzer, linter, and formatter until fixes settle, with safety controls. (#2157, 7386092)is_callable() narrowing for calls, closure conversion, offsets, and loops. (#2385, 18482c2)Stringable property names and variable-variable reads. (659446c)
preg_replace: preserves array key types and marks the replacement count as non-negative. (#2384, d894be8)mago fix and pragma lists in English, French, and Chinese. (#2157, #2109, 7386092, 05f6818)mul_add for Kan defect scores and handles watch-mode exit codes. (044b765, 116abff)No protocol changes in this release.
This release contains no merged external pull requests.
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.49.0...1.50.0
Mago 1.49.0 improves generic and assertion analysis, keeps array types precise, fixes scoped ignores, and sharpens formatter output.
Mago 1.49.0 improves generic and assertion analysis, keeps array types precise, fixes scoped ignores, and sharpens formatter output.
class-string<T>. (#2379, 0c6c397)pattern when an analyzer ignore also sets code and in. (#2375, ea0c26f)?? chains within the configured print width. (#2380, 596ce7f)use and echo statements. (#2363, ec5c55c)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.48.1...1.49.0
Mago 1.48.1 improves array and nullsafe match analysis, rejects invalid callable strings, and restores inherited generic method contracts.
Mago 1.48.1 improves array and nullsafe match analysis, rejects invalid callable strings, and restores inherited generic method contracts.
No external pull requests were merged for this release.
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.48.0...1.48.1
Mago 1.48.0 ships MANA 1.1 with richer analyzer hooks, sharper type inference, safer formatting, and tighter PHP checks.
Mago 1.48.0 ships MANA 1.1 with richer analyzer hooks, sharper type inference, safer formatting, and tighter PHP checks.
is_callable(). (#2333, f7dbdc8)@extends and @implements in all PHP attachment positions. (#2331, 1a5f625)class_alias() declarations and resolves aliases at lookup sites. (#2323, 6ae0c3c)|| and negated &&. (#2320, #2321, 0d451a8)class-string<T>. (#2330, 54871ae)array_multisort: handles variadic arrays and by-reference arguments correctly. (#2235, 9ef20b6)preg_match() and preg_match_all(). (#2205, #2350, 3df9f9c)is_a() and ::class checks. (#2352, 0aa7d51)empty-line-after-use before @mago-format-ignore-next. (#2348, dfd69a8)array_merge() key behavior before suggesting spread syntax. (#2342, e406a75)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.47.6...1.48.0
Mago 1.47.6 strengthens property and control-flow narrowing, preserves collection precision, and fixes formatter comment and string handling.
Mago 1.47.6 strengthens property and control-flow narrowing, preserves collection precision, and fixes formatter comment and string handling.
isset: marks roots defined after guarded nested offset checks. (#2303, 1da40ab)instanceof: narrows receivers and properties after nullsafe type checks. (#2308, ea927d0)strlen() comparisons. (#2307, fff0817)elseif and match. (#2312, 2a248f1)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.47.5...1.47.6
Mago 1.47.5 improves conditional and nullsafe narrowing, class-string handling, constructor analysis, and wide-shape performance.
Mago 1.47.5 improves conditional and nullsafe narrowing, class-string handling, constructor analysis, and wide-shape performance.
class-string is required. (#2285, ad348fc)$allow_string, and tests dynamic classes. (#2284, #2286, 6b73f42, a7a055c)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.47.4...1.47.5
Mago 1.47.4 improves numeric-string analysis, instanceof narrowing, formatter stability, and array-inference performance.
Mago 1.47.4 improves numeric-string analysis, instanceof narrowing, formatter stability, and array-inference performance.
($value ?? null) instanceof T. (#2249, 889e259)else and elseif. (#2150, #2237, 03d9726)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.47.3...1.47.4
Mago 1.47.3 improves pipe expressions, numeric inference, match narrowing, readonly offsets, nullsafe chains, and loop control.
Mago 1.47.3 improves pipe expressions, numeric inference, match narrowing, readonly offsets, nullsafe chains, and loop control.
preserve-breaking-pipe-expression to retain existing line breaks. (#2141, 0cfc8ec)ArrayAccess objects. (#2227, af3c576)instanceof conditions. (#2231, d6cdf19)break and continue levels across switch. (#2233, c5eff01)No external pull requests were merged for this release.
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.47.2...1.47.3
Mago 1.47.2 prevents invalid UTF-8 reporting crashes, preserves formatter semantics, and fixes several analyzer false positives.
Mago 1.47.2 prevents invalid UTF-8 reporting crashes, preserves formatter semantics, and fixes several analyzer false positives.
static factories. (#2220, 0766957)require expressions. (#2221, 38f9e2a)No external pull requests were merged for this release.
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.47.1...1.47.2
This patch release has no user-facing changes. It fixes the release pipeline so every supported target and crate can be published successfully.
This patch release has no user-facing changes. It fixes the release pipeline so every supported target and crate can be published successfully.
mago-extension to the crate publishing order. (68c0818)Full Changelog: 1.47.0...1.47.1
Extensions in any language, Sponsored by CHECK24
Thanks to CHECK24 (@check24-opensource) for sponsoring Mago's new Extension API and PHP SDK.
See the extension documentation to get started.
--skip-ignores: disables configured analyzer ignores for a run. (#2191, f05c849)array_key_exists check. (#2199, c58e48b, 7cc1739)null when inferring into a mixed parameter. (#2175, 97988bb)never. (#2179, #2206, 8d34248, c8bd837)StructureType from type_structure(). (#2186, ccde5ae)@var docblocks on global statements. (#2181, #2202, a7023c7)Closure. (#2203, d54d88e)Special thanks to CHECK24 for fully funding the Extension API's full-time development.
A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.46.0...1.47.0
This release fixes a workflow-command injection in the GitHub reporting format ( GHSA-f256-xqf4-x8pr ), adds a redundant-static linter rule and a --st
This release fixes a workflow-command injection in the GitHub reporting format (GHSA-f256-xqf4-x8pr), adds a redundant-static linter rule and a --stats shorthand, corrects a batch of generic-narrowing and late-static-binding false positives across the analyzer and codex, and speeds up the PHP parser.
Reported by Liyi Zhou, Ziyue, Strick, Maurice, and Chenchen of the University of Sydney.
case labels. (#2162, 4119141)void conditionals: stops demanding a return from conditionals in void functions. (#2160, bd85d70)self in attributes: resolves self in attributes applied to class-likes. (#2168, 7f88255)instanceof narrowing of generics parameterised by a bounded template. (#2135, a45ffec, 8b2edf6)void with never: keeps void when combined with never. (#2159, 864d0f7)missing-docs: renames the exclusion config field. (#2134, a5eab2d)Attribute: adds the missing TARGET_CONSTANT constant. (9bef302)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.45.0...1.46.0
This release teaches the analyzer to build keyed array shapes from get_object_vars() , adds @param-closure-this support and an auto-fix for overly-wid
This release teaches the analyzer to build keyed array shapes from get_object_vars(), adds @param-closure-this support and an auto-fix for overly-wide return types, introduces a linter rule preferring DateTimeImmutable::createFromTimestamp(), fixes a batch of analyzer false positives, and makes empty reports valid SARIF/JSON documents for CI.
get_object_vars() shapes: returns keyed array shapes built from the object's visible properties. (#2110, a729ce1)@param-closure-this: supports the docblock tag for typing a closure parameter's $this. (#2131, 6000d41)prefer-datetimeimmutable-create-from-timestamp: suggests the factory over new DateTimeImmutable('@...'). (#2118, 38b6152)method_exists guards on descendant members. (#2125, d1b6e9c)array_map shapes: preserves array shapes for untyped closures. (#2122, 816578a)@property-read and @property-write types. (#2079, #2108, b54a881)@property visibility: resolves tags according to call-site visibility. (#2106, a4b077d)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.44.0...1.45.0
A faster release with stronger dependent-type analysis, richer guard and linter configuration, and fixes across the CLI, formatter, analyzer, and sema
A faster release with stronger dependent-type analysis, richer guard and linter configuration, and fixes across the CLI, formatter, analyzer, and semantics.
no-missing-format-argument: detects missing format arguments. (#2062, 38857dd)missing-docs exclusions: supports configurable exclusions. (#2102, 4488055)@final validation: supports the annotation during structure validation. (#2065, 78cbbf0)do-while iterations. (#2078, 0205e49, 7afc4eb)isset flow: retains unsafe access and try/catch uncertainty after failed checks. (#2076, #2096, b70350c, 23203e5)@method calls backed by inherited methods. (#2089, fda90f8)$this and static to mixin receivers. (#2086, 07086c5)$property, not $$property. (#2066, 5d2116d)void in nullable docblock return types. (#2081, #2082, cdfd166)->value access. (#2064, 45ad41b)@require-extends classes when validating traits. (#2069, 84c0766)match-arm docblocks. (#2060, #2063, 3057c15)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.43.0...1.44.0
A fix-focused release clearing false positives across the analyzer, codex, linter, and formatter. is_callable narrowing, strict in_array , type-alias
A fix-focused release clearing false positives across the analyzer, codex, linter, and formatter. is_callable narrowing, strict in_array, type-alias recursion, ::class array keys, no-dead-store, and member-access chains. Plus sqlsrv stubs and internal HIR groundwork for the upcoming rule-based checker.
is_callable narrowing: no more false invalid-callable after narrowing to a callable type. (#2037, 938a511)in_array: keeps the value's type on a negative result instead of wrongly excluding it. (#2048, 3a69d09)redundant-logical-operation: suppressed during loop pre-condition analysis. (#2054, 4b4a7d4)::class array keys: no false invalid-array-index for literal class-string keys. (#2056, e0dc158)@no-named-arguments from native functions that accept them. (#2043, 3e77dff)no-dead-store: handles terminators and loop exits, clearing false positives. (#2052, #2053, 9f2eb74)?><?php tag-pair terminator after an abstract method. (e5f81cb)* before / as one marker, fixing a lost intersection type. (#2055, 8749c2b)AST references to CST. (#2034, 73a9ade)Node/NodeKind view and PHP surface syntax carried through the IR for the upcoming rule-based checker. (11349fd, 94927e7)mago-docblock and mago-type-syntax crates. (5deb957)A huge thank you to everyone who contributed code to this release:
Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.42.0...1.43.0
A small release adding a prefer-early-return linter rule, fixing Windows self-update , and clearing analyzer and PHPDoc false positives around is_a()
A small release adding a prefer-early-return linter rule, fixing Windows self-update, and clearing analyzer and PHPDoc false positives around is_a(), nullable destructuring, and @param on promoted properties.
prefer-early-return: new rule suggesting early returns to reduce nesting in functions. (#2031, e523ab1)is_a() with allow_string: a string subject no longer triggers a false impossible-type-comparison. (db64917)T|null keeps element types (plus null) instead of widening to mixed. (643a037)@param on promoted properties: @param T with no variable is allowed and types the property like @var. (8b9af32)self-update: extracts the .exe-suffixed binary from the archive, fixing "file not found". (805a1c3)A huge thank you to everyone who contributed code to this release:
Full Changelog: 1.41.0...1.42.0
A feature release adding call-site generic variance and a new no-duplicate-match-arm linter rule, alongside analyzer, codex, and PHPDoc fixes for impl
A feature release adding call-site generic variance and a new no-duplicate-match-arm linter rule, alongside analyzer, codex, and PHPDoc fixes for implicit Stringable, do-while narrowing, @return nullability, and enum match exhaustiveness.
no-duplicate-match-arm: new rule flags a match arm whose result duplicates an earlier arm. (#2027, a9b3775)covariant/contravariant/* type-argument modifiers parse and drive assignability. (#2025, c7ff981)@return narrowing: a docblock @return int over native ?int narrows the return instead of re-adding null. (#2020, dd8a54f)do-while conditions: the loop body is narrowed by its condition on re-entry, like while. (#2029, 496cd0a)match exhaustiveness: a self-typed enum is treated as enumerable, fixing a false non-exhaustive report. (#2019, 6c72db0)Stringable: a class declaring or inheriting __toString() now implicitly implements Stringable. (#2026, 7a81571)`code` span may cross continuation lines without an "unclosed code" error. (#2024, af95abc)Thank you to everyone who reported issues that shaped this release:
Full Changelog: 1.40.2...1.41.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →