n98/magerun2
n98/magerun2 is the Swiss Army knife CLI for Magento 2 developers, offering commands to manage cache, indexes, configuration, databases, modules, and more. It streamlines everyday development and maintenance tasks from the terminal.
Reality check first: n98/magerun2 is not a Laravel package. It is a standalone PHP CLI distributed as a PHAR that boots a Magento 2 codebase (it requires app/etc/env.php and Magento's app/bootstrap.php). There is no service provider, no facades, no config/magerun2.php. You cannot composer require it into a Laravel app and get anything useful. The realistic day-to-day leverage for a Laravel developer is one of three scenarios:
Symfony\Component\Process\Process.Install (no Composer in your app):
# global, versioned
curl -sSLO https://files.magerun.net/n98-magerun2.phar
chmod +x n98-magerun2.phar
sudo mv n98-magerun2.phar /usr/local/bin/magerun2
# verify
magerun2 --version # 10.1.0 is the current line
php -v # must satisfy the phar's PHP floor (v5+ targets modern PHP 8.x)
Look here first, in this order:
magerun2 list # the whole command surface, grouped by namespace
magerun2 help cache:clean # per-command options and flags
magerun2 sys:info # PHP, Magento edition/version, DB, cache backends
magerun2 sys:check # readiness/sanity diagnostics
magerun2 db:compatibility # NEW in 10.1.0 — DB support + upgrade paths
db:compatibility (added 10.1.0) is now the first command to run on an inherited or freshly upgraded instance — it tells you whether the DB flavor/version is actually supported before you start debugging weirdness elsewhere.
First use case that pays for itself: replace an ad-hoc bin/magento deploy ritual with one idempotent sequence.
magerun2 cache:flush && magerun2 index:reindex && magerun2 sys:check
Run it from your Laravel deploy job (Envoy, a queued job, a Process::run()) and you get the same result from CLI, CI and Docker entrypoints — that portability is the whole point of the tool.
Wrap it, don't inline it. In Laravel code, treat magerun2 as an external binary behind one small class:
final class Magerun
{
public function __construct(private string $bin, private string $rootDir) {}
public function run(array $args, int $timeout = 300): ProcessResult
{
return Process::timeout($timeout)
->path($this->rootDir)
->run([$this->bin, ...$args, '--no-interaction']);
}
}
// $magerun->run(['cache:clean', 'config', 'full_page']);
// $magerun->run(['db:dump', '--strip=@development', 'staging.sql.gz']);
Always pass --no-interaction. Several commands prompt otherwise, and a blocked prompt inside a queued job is a silent timeout.
The commands that actually earn their keep in ops work:
# cache / index — the daily loop
magerun2 cache:clean # invalidate, keeps FPC warm-ish
magerun2 cache:flush # full wipe
magerun2 cache:list
magerun2 index:list
magerun2 index:reindex # all, or pass an indexer code
# data movement — use this instead of mysqldump
magerun2 db:dump --strip=@development prod-$(date +%F).sql.gz # sanitized
magerun2 db:import prod-$(date +%F).sql.gz
magerun2 db:info
magerun2 db:compatibility # 10.1.0+ — DB version support & upgrade options
magerun2 db:query "SELECT COUNT(*) FROM sales_order"
# stores / config, without clicking through admin
magerun2 sys:store:config:base-url:set --store=default --unsecure --secure ...
magerun2 config:store:set web/unsecure/base_url https://shop.test/ --scope=stores --scope-id=1
magerun2 config:store:get web/unsecure/base_url
# users & access recovery
magerun2 admin:user:list
magerun2 admin:user:change-password admin 'NewPassw0rd!'
magerun2 admin:user:create --admin-user=ops --admin-password='...' --admin-email=... --admin-firstname=... --admin-lastname=...
# cron & modules
magerun2 sys:cron:list
magerun2 sys:cron:run <job_code>
magerun2 module:list
magerun2 setup:upgrade
# mail testing (10.1.0: recipient can now be a positional arg)
magerun2 sys:email [email protected] --subject='SMTP check'
db:dump --strip=@development is the single most valuable feature if your team clones production data down: it drops logs, sessions, quotes, customer PII tables by group so you never ship a GDPR incident in a dev artifact.
CI/CD and container patterns. Put it in the image and call it from entrypoint/Make targets, mirroring how you'd call artisan:
COPY --from=... /usr/local/bin/magerun2 /usr/local/bin/magerun2
USER www-data
CMD ["sh", "-c", "magerun2 cache:flush --no-interaction && php-fpm"]
Because it's a PHAR with no autoload coupling to the app, the same artifact works across Magento versions within a major — pin the PHAR version in your image and bump deliberately.
Build-speed: fast DI compiler (10.1.0). 10.1.0 adds a downloader/installer for a prebuilt fast DI compiler binary (PRs #2164/#2165). If setup:di:compile dominates your deploy time on a large catalog, look for this in list under the setup/dev namespace and wire it into your pipeline ahead of setup:upgrade. Treat it like a toolchain artifact: pin the binary version and checksum it in CI rather than fetching at runtime on production.
Interactive debugging. For exploratory work, magerun2 dev:console gives you a REPL with the Magento DI container booted — that's the closest analogue to php artisan tinker and it's where you'll actually learn the data model. dev:profiler:enable / dev:template-hints:enable are the Magento equivalents of dropping Debugbar in.
MCP and command scoping (10.1.0). The tool now supports disabling commands globally and for MCP exposure using wildcard patterns (PR #2172), and 10.1.0 also fixes MCP argument handling and repeated-execution regressions in the customer commands (PR #2178). For a Laravel developer this is the interesting new surface: if you're wiring Magento operations into an agent or your own MCP client, you can now lock down exactly which commands are reachable instead of exposing the entire command tree. Start with a deny-by-default allowlist (e.g. permit cache:*, index:*, sys:info; wildcard-block destructive db:*, admin:user:*, setup:*) and widen deliberately.
Extending it (the module API). If you're writing a bridge, don't shell out for everything — commands are plain Symfony Console commands extending \N98\Magento\Command\AbstractMagentoCommand, and you can register your own via the tool's YAML config (global ~/.n98-magerun2/config.yaml, plus project-level config) and scaffold with magerun2 gen:command. This is the pattern worth stealing for your own Laravel tooling: PHAR + YAML-registered command modules + Symfony Console.
bin/magento replacement. They overlap heavily but diverge; magerun2 often wraps or shortcuts core commands. Pick one canonical path per task in your runbooks or you'll get confusing double-execution in deploy scripts. The 10.1.0 fast-DI downloader is a good example: it complements setup:di:compile, it doesn't replace it.db:dump/reindex runs die on the default CLI memory limit: php -d memory_limit=-1 /usr/local/bin/magerun2 .... And if you run it as root on a box where the web server runs as www-data, you will chown var/, generated/, pub/static and spend an afternoon on 500s. Always run as the app user, or chown -R immediately after.--root-dir when you're not cd'd in. From a Laravel command whose CWD is your app root, pass the Magento docroot explicitly rather than relying on the working directory.--no-interaction on every invocation; also beware commands that ask for confirmation on destructive operations (db:import over an existing DB). 10.1.0 fixed the cron job selector height (PR #2169) — cosmetic, but a reminder that these selectors are interactive and still block automation.Process::exitCode(), not stdout scraping — output format is not a stable API across releases. Log -vvv output on failure only; verbosity flags (-v, -vv, -vvv) are the primary debugging lever when a command fails silently.db:compatibility added in 10.1.0 gives you a cheap pre-flight check for the DB half of that equation.mcp/sdk dependency was bumped three times inside this release cycle (0.7.1 → 0.8.0 → 0.8.1) and there were MCP-specific bug fixes. If you depend on MCP behavior, pin the PHAR exactly and test upgrade-to-upgrade — a 0.x SDK underneath an unstable surface is not a stable contract.NOASSERTION, not a clean SPDX identifier. Before bundling the PHAR into a distributed commercial artifact or a client deliverable, confirm the actual license terms from the repo's LICENSE file — don't infer MIT from "it's on GitHub."Magerun class above) so you can swap the binary, fake it in tests, and keep Magento-specific strings out of your domain code.magerun2 list and the repo's command source directly.How can I help you explore Laravel packages today?