recca0120/laravel-tracy
Laravel Tracy brings the Tracy debugger to Laravel, offering rich error pages, exception handling, dump/dumper helpers, and a debug bar for inspecting queries, requests, and application state during development.
Install as a dev dependency so it never ships to production:
composer require --dev recca0120/laravel-tracy
Laravel 5.5+ auto-discovers Recca0120\LaravelTracy\LaravelTracyServiceProvider. On older versions add it to config/app.php under providers, plus the Tracy facade under aliases if you want Tracy::dump().
Publish the config and read it end-to-end before touching anything else — it is the single place that controls behaviour:
php artisan vendor:publish --provider="Recca0120\LaravelTracy\LaravelTracyServiceProvider"
// config/tracy.php (typical shape)
return [
'enabled' => env('APP_DEBUG', false),
'showBar' => env('APP_DEBUG', false),
'strictMode' => env('APP_DEBUG', false),
'maxDepth' => 3,
'maxLen' => 150,
'panels' => [ /* built-in + your own panels */ ],
'decorators' => [ /* dump formatters */ ],
];
First use case: with APP_DEBUG=true, load any HTML page and confirm the Tracy bar renders at the bottom right. Then deliberately throw an exception in a controller — you should get Tracy's blue-screen page instead of Ignition/Whoops, with a full stack, source excerpt, and request/session context. Finally, drop bdump($user) in a controller; the value appears in the bar's Dumps panel rather than inline in the page.
Where to look first when something is off:
config/tracy.php (enabled, showBar, panels),boot() — it calls Debugger::enable() and wires Laravel's container into Tracy,Tracy\Debugger::getBar() at runtime to inspect what panels are actually registered.Dumping without breaking the response. Prefer bdump() / \Tracy\Debugger::barDump() for anything inside a request that returns HTML: it queues the value for the bar instead of echoing it into the middle of your markup. Use dump() (Tracy's, not Symfony's) when you need output in a console command or a streamed response.
bdump($order->toArray(), 'order'); // bar panel, labelled
\Tracy\Debugger::dump($collection); // inline, works in CLI
\Tracy\Debugger::timer('import'); // ... later
bdump(\Tracy\Debugger::timer('import')); // seconds elapsed
Panels are the main extension point. The package ships panels for request, session, auth, routing, database/queries, and mail. Enable or reorder them in the panels array. A custom panel is just a class implementing Tracy\IBarPanel:
class FeatureFlagPanel implements \Tracy\IBarPanel
{
public function getTab(): string
{
return '<span title="Flags">flags</span>';
}
public function getPanel(): string
{
return '<h1>Flags</h1><pre>' . htmlspecialchars(print_r(flags()->all(), true)) . '</pre>';
}
}
Register it in config/tracy.php under panels, then php artisan config:clear. This is the cleanest way to surface domain state (tenant id, queue name, feature flags) on every page.
Dump decorators. For domain objects you dump constantly (money value objects, DTOs, models), add a decorator so the dumps panel shows something readable instead of 40 private properties. Decorators live in the decorators config key and are the difference between a useful bar and a wall of nested arrays.
Exception handling. Tracy takes over error and exception rendering in development. Keep Laravel's Handler as the source of truth for reporting (report(), $dontReport) and let Tracy own only presentation. If you have custom render() logic for API 404s/validation, verify it still fires — Tracy's blue screen is for uncaught throwables, not for HttpExceptions Laravel renders itself.
Console and queues. There is no HTTP bar, so set the mode/enabled flags so Tracy doesn't fight with Artisan output, and rely on Debugger::dump() writing to stdout plus your normal log channel. Debugger::enable(Debugger::DEVELOPMENT) is worth calling explicitly at the top of a throwaway command.
Editor integration. Set the file-link format in config to your IDE so blue-screen stack frames are clickable:
'fileLinkFormat' => 'phpstorm://open?file=%file&line=%line',
composer why-not recca0120/laravel-tracy against your Laravel/PHP version (Laravel 10/11, PHP 8.2/8.3) before committing. Pin the version, and keep a note on how to rip it out — it hooks error handling globally, so an abandoned package is not a cheap thing to leave in require-dev.APP_DEBUG and confirm enabled/showBar are false in staging, not just production.APP_DEBUG=true and your test suite, that's why — tests run without the bar and without the handler swap.dump() name collision. If symfony/var-dumper is loaded, the global dump() may resolve to Symfony's, not Tracy's, and end up in storage/logs or the HTTP response. Use bdump() or the fully qualified \Tracy\Debugger::dump() when it matters.accepts/content-type guard narrow; for AJAX use bdump() and inspect the response headers/payload instead of expecting a bar.maxDepth and maxLen silently cut structures — a "missing" relation is often just depth 4. Raise them temporarily rather than rewriting your dump; but drop them back down, because large Eloquent collections will blow memory when fully expanded alongside a screenshot.panels or decorators does nothing until php artisan config:clear (or config:cache in a deploy). This is the most common "the package is broken" false alarm.barryvdh/laravel-debugbar (Laravel-native, actively maintained), Clockwork, or Ray. Tracy's blue screen and dump ergonomics are genuinely better in some workflows, but you're trading maintenance risk for them.How can I help you explore Laravel packages today?