CLI tool
nette/tracy avatar
nette/tracy

Tracy: a PHP debugger that hides itself in production

😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.

1,834 stars217 forksPHPNOASSERTION

At a glance

What is it?
Tracy is Nette's debugging library for PHP, and the part that makes it more than a dumper is the way it changes behaviour depending on where it runs. In development it renders errors as an interactive page with the failing source line highlighted, and in production it detects the environment, logs the error instead of displaying it, and shows the visitor a friendly message.
Who is it for?
Adopt Tracy if you work in PHP and want one debugging surface that behaves differently in development and in production, so that the same code can show a detailed error to you and a neutral message to a visitor. Do not adopt it as a profiler replacement for long running jobs, and do not enable it in a context where the environment detection cannot tell development from production.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One debugging surface, two behaviours

Tracy is described as a useful helper for everyday PHP programmers, designed to facilitate debugging PHP code, to hint and correct you just like a good friend watching your back, and to give a visualization of errors that the README calls rather colourfully a damn cool one.

The argument the README makes for why that matters is about the language rather than the tool. PHP is a perfect language for making hardly detectable errors because it gives great flexibility to programmers, and Tracy\Debugger is more valuable because of that, an ultimate tool among the diagnostic ones.

The design decision that follows from that argument is the one in the section on development and production mode. As the README puts it, Tracy is quite talkative, which can be appreciated in the development environment, while on the production server it would cause a disaster, because no debugging information should be displayed there. Tracy therefore has environment auto-detection, and if the example is run on a live server, the error will be logged instead of displayed, and the visitor will only see a user-friendly message.

That is the part to evaluate first, because it is the part that decides whether the library is safe to leave enabled. A debugger that renders a stack trace and a source excerpt to whoever triggered the error is a serious disclosure risk in production, and the mechanism that prevents it is environment detection, which is a heuristic and not a guarantee.

The library is part of the Nette family, the licence file is a New BSD licence, the last push was on 2026-10-14, and the recent releases are v2.11.4 from 2026-04-22, v2.12.0 from 2026-05-04 and v2.12.1 from 2026-08-18. The project site is tracy.nette.org and the source lives in nette/tracy.

Composer, a package download, or a phar

The installation section is short, which is what you want from a library that most projects will add to a composer.json and never think about again.

The recommended way is via Composer:

shell
composer require tracy/tracy

Alternatively, you can download the whole package or the tracy.phar file, and the phar is linked from the releases page. A single file phar has a specific value here, because it is the difference between a library you can drop next to a script and one you need a dependency manager and an autoloader for.

The compatibility statement is precise: Tracy is compatible with PHP 8.2 to 8.6. That is a five version window, which is wide enough to be comfortable and narrow enough that a project still on PHP 8.1 has to look elsewhere.

The repository layout shows what a mature library of this kind carries. There is src/ for the code, tests/, a docs/ directory, tools/, and an examples/ directory that doubles as the documentation of what the thing does. The examples are the interesting part for evaluation, and their names describe the feature set precisely: dump.php, barDump.php, dump-snapshot.php, exception.php, fatal-error.php, notice.php, warning.php, output-debugger.php, preloading.php, redirect.php, ajax-fetch.php, ajax-jquery.php and a log/ directory.

Two of those deserve a mention. The output-debugger example is the one that changes how a var_dump looks, and the ajax-fetch and ajax-jquery examples are about the debugging of AJAX calls, which the repository topics list as a feature of the project.

Debugger::enable() before any output

The activation rule is a single line of prose and three lines of code, and the prose is the part that matters.

Tracy is activated by calling the Tracy\Debugger::enable() method as soon as possible at the beginning of the program, before any output is sent.

php
use Tracy\Debugger;

require 'vendor/autoload.php'; // alternatively tracy.phar

Debugger::enable();

The before any output is sent condition is not a style preference. The Tracy Bar is injected into the page, and it is injected as HTML at the end of the document, so if your script has already written a byte to the output buffer, the panel cannot be placed properly and the debugging experience degrades. In a framework with a front controller that is easy to honour, and in a script that echoes as it goes it requires an explicit reorder.

The second thing to notice is where the enable call sits relative to the autoloader. The require line comes first, because the class has to exist before it is called, and the comment notes that tracy.phar is the alternative to the vendor directory. That is the whole bootstrap.

And then there is the development mode parameter, which the README explains in the section on the Tracy Bar. The bar is only visible on localhost for security reasons, so if you do not see it, it may mean that Tracy is running in production mode. To test whether it works, you can temporarily put it into development mode using the Debugger::enable(Debugger::Development) parameter.

That parameter is the manual override, and it is also the tool you use in development to make sure the bar is there at all.

The Tracy Bar and the panels you can add

The Tracy Bar is the piece of the interface most people recognise, and the README describes it in one paragraph.

It is a floating panel, displayed in the bottom right corner of a page, and you can move it with the mouse. It will remember its position after the page reloading, which is a small detail that matters when you use it every day, since a bar that jumps back to the corner on every reload gets in the way.

If you do not want to show the Tracy Bar at all, the configuration is one static property:

php
Debugger::$showBar = false;

The bar is also a container. You can add other useful panels to it, the README says you can find interesting ones in the addons on componette.org, or that you can create your own, with the extension documentation on the Tracy website.

That is the design that makes Tracy more than an error page. The error visualizer is the part everybody sees, and the bar is the part that turns it into a development environment: a place to see the request, the environment, the session and the profiler output without leaving the page you are working on.

The repository topics reflect that spread of use, and they list error-handling, dump-variables, dumper, profiler, ajax, debugger and php-errors, which is a fair summary of a library that does error rendering, variable dumping, a request profiler and command line support, and that is debuggable over AJAX as well as in a normal page.

Errors, exceptions and fatals rendered the same way

The visualisation section shows what the library actually replaces, and the before and after is the point.

The before is PHP's own output, a parse error in the page source, or an uncaught exception with a stack trace of frames, file names and line numbers, which the README says is not so easy to navigate through.

The after, the README says, is that both errors and exceptions are displayed in a completely different form. The error message literally screams, you can see a part of the source code with the highlighted line where the error occurred, a message clearly explains the error, and the entire site is interactive.

And then the part that is unusual. Fatal errors are captured and displayed in the same way, with no need to install any extension. That matters more than it sounds. A fatal error in PHP is, by default, an uncaught fatal printed inline in the middle of whatever output your script had produced so far, and in a page that has already sent headers it is often a blank screen with the explanation in the log. Tracy renders it as a page like any other error, with the source and the line, without an extension like xdebug having to be installed.

The same treatment covers the errors that are usually missed. Errors like a typo in a variable name or an attempt to open a nonexistent file generate reports of E_NOTICE or E_WARNING level, and the README notes these can be easily overlooked or completely hidden in a web page graphic layout.

The interactive part is the difference in practice. A stack trace tells you where the code went wrong. An interactive page lets you open the frames, look at the variables at each one and read the source around the failing line, which is the difference between knowing the line number and knowing the bug.

strictMode and the E_ALL default you may not know about

There is a configuration detail in the visualisation section that has a side effect worth understanding, and the README flags it explicitly.

By default, a notice can be displayed like an error:

php
Debugger::$strictMode = true; // display all errors
Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // all errors except deprecated notices

So strictMode controls how loud the library is about lower severity diagnostics, and the second form is the one most projects will want, since deprecation notices are noise once a codebase is large.

The side effect is stated in a note at the end of the section. Note that Tracy when activated changes the error reporting level to E_ALL. If you want to change this, do so after calling enable().

That ordering requirement is a real constraint on integration. If your application sets error_reporting somewhere in a bootstrap file, that assignment has to come after the enable call, or Tracy will set it back to E_ALL and your project's carefully chosen level will be lost. It is a one line ordering rule, but it is the kind of thing that silently changes what your logs contain, and it is worth checking in an existing codebase rather than assuming.

The development and production split interacts with all of this. In production, the error is logged rather than displayed, and the visitor sees a user friendly message. The same strictMode that makes a typo in a variable name loud in development has no visible effect in production, because the output does not reach the browser.

Editorial conclusion

Adopt Tracy if you work in PHP and want one debugging surface that behaves differently in development and in production, so that the same code can show a detailed error to you and a neutral message to a visitor. Do not adopt it as a profiler replacement for long running jobs, and do not enable it in a context where the environment detection cannot tell development from production. Verify first that your PHP version is between 8.2 and 8.6, that Debugger::enable() runs before any output is sent, and that your deployment actually changes the environment detection, because that detection is what keeps the debugging output out of production.

Frequently asked questions

How do I install Tracy for PHP?

The recommended way is composer require tracy/tracy. Alternatively you can download the whole package or the tracy.phar file linked from the releases. Tracy is compatible with PHP 8.2 to 8.6.

Why does the Tracy Bar not appear on my page?

The README explains that Tracy is only visible on localhost for security reasons, so a missing bar may mean it is running in production mode. You can test it temporarily with the Debugger::enable(Debugger::Development) parameter.

Does Tracy change the PHP error reporting level?

Yes. The README notes that Tracy when activated changes the error reporting level to E_ALL, and that if you want to change this you should do so after calling enable(). Debugger::$strictMode controls how the lower severity diagnostics are displayed.

What does Tracy do with fatal errors?

Fatal errors are captured and displayed in the same way as other errors, with the source code and the highlighted line, and with no need to install any extension.

Official sources

  1. Issues
  2. nette/tracy on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nette-tracy.svg)](https://hysenlabs.com/projects/nette-tracy)

Was this useful?