Kint - a powerful and modern PHP debugging tool.

Last update: May 14, 2022

Kint - debugging helper for PHP developers


What am I looking at?

At first glance Kint is just a pretty replacement for var_dump(), print_r() and debug_backtrace().

However, it's much, much more than that. You will eventually wonder how you developed without it.


One of the main goals of Kint is to be zero setup.

Download the file and simply


require 'kint.phar';

Or, if you use Composer:

composer require kint-php/kint --dev



Kint::dump($GLOBALS, $_SERVER); // pass any number of parameters
d($GLOBALS, $_SERVER); // or simply use d() as a shorthand

Kint::trace(); // Debug backtrace
d(1); // Debug backtrace shorthand

s($GLOBALS); // Basic output mode

~d($GLOBALS); // Text only output mode

Kint::$enabled_mode = false; // Disable kint
d('Get off my lawn!'); // Debugs no longer have any effect

Tips & Tricks

  • Kint is enabled by default, set Kint::$enabled_mode = false; to turn it completely off.
    The best practice is to enable Kint in a development environment only - so even if you accidentally leave a dump in production, no one will know.
  • See the buttons on the right of the output? Click them to open a new tab, show the access path for the value, or show a search box.
  • To see the output where you called Kint instead of the docked toolbar at the bottom of the page add the line Kint\Renderer\RichRenderer::$folder = false; right after you include Kint.
  • There are a couple of real-time modifiers you can use:
    • ~d($var) this call will output in plain text format.
    • +d($var) will disregard depth level limits and output everything.
      Careful, this can hang your browser on large objects!
    • !d($var) will expand the output automatically.
    • -d($var) will attempt to ob_clean the previous output and flush after printing.
    • You can combine modifiers too: ~+d($var)
  • Double clicking the + sign will open/close it and all its children.
  • Triple clicking the + sign in will open/close everything on the page.
  • Add heavy classes to the blacklist to improve performance:
    Kint\Parser\BlacklistPlugin::$shallow_blacklist[] = 'Psr\Container\ContainerInterface';
  • To change display theme, use Kint\Renderer\RichRenderer::$theme = 'theme.css';. You can pass the absolute path to a CSS file, or use one of the built in themes:
    • original.css (default)
    • solarized.css
    • solarized-dark.css
    • aante-light.css
  • Kint has keyboard shortcuts! When Kint is visible, press D on the keyboard and you will be able to traverse the tree with arrows, HJKL, and TAB keys - and expand/collapse nodes with SPACE or ENTER.
  • You can write plugins and wrapper functions to customize dump behavior!
  • Read the full documentation for more information


Jonathan Vollebregt (jnvsor)
Rokas Šleinius (raveren)


Licensed under the MIT License

  • 1. Proper way to include Kint in CMS's?

    I've placed the Kint folder in the root of my site (/home/mydomain/public_html/devtools/kint/Kint.class.php) so I can use it in whatever I'm working on.

    I've directly added the include_once in a basic PHP file and tested it, and it worked great. I also removed the include from the file and added it in php.ini under auto_prepend_file which also worked.

    However, whether I directly include or use auto_prepend in either one of my WordPress sites or Drupal sites, I just get a WSOD in either one of them. Even turning on error reporting via:

    ini_set('display_errors', 1);

    to try and troubleshoot why it's not working, results in no errors shown or logged, just a WSOD. In fact, I would prefer to keep it always enabled in php.ini but since it breaks my CMS's I have to disable it there.

    Any suggestions?


    Reviewed by STaRDoGG at 2014-12-03 21:22
  • 2. RFC: Major version bump - Kint 2.0-dev

    Today, I've pushed something to jnvsor/kint/2.x-dev. I've been working on this for about 3 months now, I've basically rewritten all of Kint from the ground up.

    I'd like this to be a starting point for a new major version of kint.


    #50 #175 #203 #197 #182 #177 #176 And probably more too...


    Lots of kint is very rigid. It's not designed with extensibility in mind. Most of the time you want to customize behaviour you have to edit kint source code yourself. In some of the best cases you have to dump new files inside kint's directory tree. These are bad things for anyone that wants to install an update.

    My branch has a very extensive plugin system, to the point where you can pretty much replace both the parsing and rendering systems entirely without ever touching kint source code. This makes it possible for user provided solutions to certain feature requests: #107 (High prio for over 2 years! :D) #185 #94 #189 #87 : No longer applies: All the config system did was set a few properties on the kint class, you can do that from anywhere and have an easier time of it and a cleaner codebase

    Additionally, because the parser/renderer/plugins etc are properly decoupled, it can be meaningfully unit tested. (This provides a start at #26)

    In fact, it's so decoupled that if you want you can just call the parser and renderer and leave the main Kint class out of the loop entirely. (TODO: Some plugins get hardcoded info from Kint class, max_str_length in Kint_Object_Blob for example)


    Kint master internals are Lovecraftian - peer at them too long and your sanity will be devoured by the great old ones.

    Sarcasm aside - kint seems to have been developed very organically, which isn't necessarily bad but tends to add technical debt.

    • We have a parser that outputs HTML, so if you want a decorator that doesn't you first have to unparse the HTML (See 2db0845f7a9ac642d09947e6f000e57e3b91ac64 )
    • For some reason the parser is actually a child class of the data objects it's supposed to produce (???)
    • The parser tries valliantly (And fails miserably) to prevent recursion "ghosts" on referenced arrays at the root level (See #203, #204) I've explained why this can't be done before, but that's a complex topic so I'll leave that for the other issues.
    • Parser plugins almost exclusively produce html, so they're by definition reliant on the rich renderer. Checks on Kint::$enabledMode are strewn throught the parser system.
    • It's a deck of cards. Everything is far too tightly coupled.

    Long story short: I gutted everything. Now the parser just returns data, and the renderer takes that data and does whatever with it. The individual parts are all smaller: The rich renderer is 10% smaller, the parser is 40% smaller, the JS renderer (The example for the unparsing problem) is also 40% smaller.

    Lots of special case code has been moved from the parser and main kint class into plugins where they belong: Backtrace handling, tabular display, etc

    Basically it's a big-ass cleanup and for the most part easier to grep

    The catch

    Well not catch so much as caveats.

    This is a work in progress

    While it works fine for basic debugging, most of the plugins aren't ported yet. ClassStatics, ClassMethods, Microtime, Closure and Trace have all been ported, but there's still a small mountain worth of missing ones (Including things like the tabular display that used to be hardcoded in the parser)

    The plain renderer also hasn't been ported yet, so PLAIN WHITESPACE and CLI output modes won't work till that's done.

    It's got a lot of good stuff, but it's not feature parity (Yet)

    This is not a stable API

    I'm very happy with the way the parser works. I've put a lot of thought into it and it seems to work beautifully. The problem is the renderer.

    The renderer needs to know how to take data and turn it into output. Currently, the parser plugins can add a "Class" to a representation (Tab) and the renderer maps that class to a renderer plugin. This works fine but there's no way to alter the way a header is rendered, only a tab. I intend to make large changes to the plugin system until it's working well enough.

    Here be monsters.

    It's slow

    Last I checked the parser was some 1000% faster than the old parser, but the renderer is significantly slower and it all evens out at a 50% slowdown (Last I checked... I've changed a lot since then)

    I'm not actually sure why this is - when I stub out all the relevant functions so it's just outputting enough to let me know it's actually outputting at all, it's still far slower. I'm guessing it's some PHP internal optimization - probably something in static methods that PHP deems pure so it caches the result or some such.

    All that said, it's not too slow - I don't see any difference in normal use. The pliability benefits of the new plugin system outweigh a speed difference I can't tell exists without tools. I'll take a closer look after I'm satisfied with the API.

    It works in PHP 5.1

    While I'd like to make a smiley and say this is just a joke about kint's strict version requirements (next month 5.1 will have been EOL for a decade) the truth is it's so old I couldn't find a way to get it working so while it absolutely should work on 5.1 I have NO way of proving that. If anyone can test it for me (Or show me an easy way to do it myself) that would be a big help.

    The code style

    Code style conversations are always purely subjective. Subjective enough to turn into flame wars so I'm not going to bother rooting for the code style I use here, or against the code style in master.

    Instead I'm going to argue on consistency. Consistent code style is good right? We can agree on that right? Right?...

    Anyway, I'm not very consistent. I drift between K&R, PSR, trololol-minified-php-ftw, and generally don't have anything consistent enough to write my own code style rules. So I let my computer do it for me.

    php-cs-fixer guarantees consistent code. It also lets me write whatever sloppy nonsense I want to then fix it with a simple command. Because it's a program, we could also enforce it alongside a test suite with CI.

    There are other purported php formatters out there but of the few I've tried php-cs-fixer is the best (One of them actually changed method naming styles and broke a system on me once... Yay) and the defaults are fairly sane and PSR compliant. Most importantly, I personally can attest that if I stuck with master's code style I'd have been at it for another 3 months :)

    What needs to be done

    If anyone has any ideas that could clean up the architecture I've made here that would be great

    • I want to tweak the rendering system a bit so that plugins can effect headers as well as tabs, so I'll probably end up gutting that for the fifth time.
    • It needs to be tested for 5.1 compat
    • I need to find out what's going on with rendering performance. This should wait until all plugins are ported as that can effect performance too.
    • A lot of plugins need to be ported
    • A test suite would be nice, but lets get things working first.
    • I want to decouple a few things that shouldn't be in the main Kint class (max_str_length should probably be on the renderer not the Kint class, the Trace plugin should have a configurable alias tracking system, etc)
    Reviewed by jnvsor at 2016-07-30 15:44
  • 3. Deprecate blacklist/whitelist in favour of blocklist/allowlist

    There's the $parser_plugin_whitelist and there's the BlacklistPlugin with quite some occurrences of these problematic strings. Of course also in the test. I guess we can't simply replace the one strings provided by PHPUnit but maybe let's start by providing alternatives for the ones we currently have in Kint and deprecate the old ones for now.

    Reviewed by leymannx at 2020-07-20 08:16
  • 4. Make kint minitrace more readable

    use light-grey color (#ddd) makes the minitrace very difficult to read in almost all kint themes. The only theme in which use #ddd has sense is "solarized-dark"


    Reviewed by willzyx-dev at 2016-05-21 15:44
  • 5. Issue on Windows console

    Calling s() from console works great in Linux, however in Windows it doesn't show the unicode table drawing characters correctly.

    I accept anything ranging between:
    a) disable these characters altogether,
    b) replace them with ordinary dashes and pipelines, or c) create a fix to show them correctly on Windows.

    Reviewed by DRSDavidSoft at 2016-05-19 16:40
  • 6. Error message: Cannot access non-public member

    I get this error. As I noticed, this only applies to static private property

    An exception (ReflectionException) was thrown in phar://<ROOT>/wp-content/plugins/zu-plus/includes/debug/kint.phar/src/Parser/ClassStaticsPlugin.php on line 94 while executing Kint Parser Plugin "Kint\Parser\ClassStaticsPlugin". Error message: Cannot access non-public member zu_Plus::$zukit_root

    What could be the problem?

    Reviewed by picasso at 2021-04-06 08:38
  • 7. Recursion detection by reference

    As discussed in this is recursion tracking by reference. The array and object references are collected in a "register" and if they are encountered a second time, that is considered a recursion.

    One of the benefits of this approach is that arrays are never tainted with markers, and at any time a plugin can pick the parsed array variable as it is.

    I do use hashes to address the object references, but that's because it is faster that way instead of traversing the whole list of knownObjects.

    @jnvsor has some concerns about memory leaks and performance, and I'll be looking forward for ways how to test these cases. So far I've only done the examples from and the ParserTest.php unit test, and both work OK.

    Structurally, the output of the recursions is the same as from var_dump(). Here's what I used to compare:

    include 'vendor/autoload.php';
    $a = ["Array 1"];
    $b = ["Array 2"];
    $a[] = &$b;
    $b[] = &$a;
    $r = (object) ['a' => 23, 'b' => 45];
    $r->c =& $r;

    There is a screenshot of the output here

    Reviewed by kktsvetkov at 2020-08-12 23:14
  • 8. View data in CLI

    I have file tst.php

    require_once 'vendor/autoload.php';
    d([1, 2, 3]);

    run this file in cli with php-kint v3 2019-06-14_11-02-19

    and with php-kint v1 2019-06-14_11-05-48

    Why data displaying is not correct in php-kint v3?

    Reviewed by loveorigami at 2019-06-14 08:13
  • 9. Recursion bug - leaving marker in arrays in certain conditions

    Don't know why exactly but:

    $a = ["Array 1"];
    $b = ["Array 2"];
    $a[] = &$b;
    $b[] = &$a;

    This shows the marker in $a in the second call.

    I'm doing an experimental overhaul of the parser (It's looking good) so I'll probably come across more of these things.

    Reviewed by jnvsor at 2016-05-21 18:37
  • 10. add option to collapse all children

    When you for instance have an array of objects, you don't always want to see the contents of the objects, just the headers.

    I imagine the icon to look like 3 horizontal lines

    Reviewed by winkbrace at 2013-06-06 09:01
  • 11. Bug ? Wut ?


    // in private function _getAllItems($url)
    // from class Alienware extends \GiveMeSomeGoodNews\Core\Controller
    \Kint::dump( $items ); //
    var_dump( $items );
    // ...


    a:4:{i:0;a:4:{s:5:"title";s:48:"Magicka: Wizard Wars Alienware Robe Key Giveaway";s:4:"guid";s:40:"ddcafe286003d79e0083dc32234b88a874c68aba";s:11:"description";s:513:"Go down in a blaze of glory with this exclusive Alienware Arena key for the Alienated Speedster robe. At the cost of 100 HP, you'll gain a 4% speed boost to outmaneuver your enemies and claim victory over their burnt corpses. With amazing Steam reviews like this: 8 elements, loads of fun, and beautiful C-H-A-O-S! Seriously get this game ASAP-[Nii-Wizards] Bacitoto Why haven't you gotten your exclusive robe and joined the action yet? Additional batch of keys added! About Magicka: Wizard Wars: Mag...";s:7:"pubDate";s:10:"1411954938";}i:1;a:4:{s:5:"title";s:47:"Kill The Bad Guy 33 Steam Discount Key Giveaway";s:4:"guid";s:40:"c3af1d6c9caae31d9f3058d51cd90c6808f2d560";s:11:"description";s:502:"Locate the target, execute a brilliantly sadistic plan, and watch the end result with this 33% Steam Discount for Kill The Bad Guy. Serving justice is just the side effect. Executing a brilliant plan intent on inflicting brutal pain is the real objective in Kill The Bad Guy. About Kill The Bad Guy: Does everyone deserve a second chance? Can crimes ever be forgotten? Hiding behind the mask of the average man on the street, and furtively blending into the background, many war criminals, ex-Mafia...";s:7:"pubDate";s:10:"1411954938";}i:2;a:4:{s:5:"title";s:39:"Broforce 25 Steam Discount Key Giveaway";s:4:"guid";s:40:"a4f301e1f8fc8d3414c2be65cd23f658ed55bebc";s:11:"description";s:504:"Never has it been more fun to turn the rest of the world into your own personal Brodom. Unleash liberty and freedom onto the rest of the world with this 25% Steam discount for Broforce. Bro with others or all on your own as the world once again turns to Broforce to raise the world to Brocon 1. So, what are you waiting for, a Brovitation? About Broforce: When evil threatens the world, the world calls on Broforce - an under-funded, over-powered paramilitary organization dealing exclusively in exce...";s:7:"pubDate";s:10:"1411954938";}i:3;a:4:{s:5:"title";s:45:"Shadow Warrior 75 Steam Discount Key Giveaway";s:4:"guid";s:40:"1764699fa1773b09b3e2d79558784d6f05b559b0";s:11:"description";s:505:"Need to stop a demonic invasion? A combination of guns, katana, magic, and wit are your weapons. Take this 75% Steam discount code for Shadow Warrior and decide what combination of death you will bring to the hoards of invading demons. About Shadow Warrior: Shadow Warrior tells the offbeat tale of Zilla Enterprise’s corporate shogun, Lo Wang, who is ordered by his employer to track down and acquire a legendary blade known as the Nobitsura Kage. Forced into a timeless battle, Lo Wang learns of th...";s:7:"pubDate";s:10:"1411954938";}}
    Reviewed by Glaived at 2014-09-29 02:21
  • 12. Kint version

    I suggest adding in Kint the ability to know the current version. Now Kint itself does not store the version number anywhere and you can find it only by looking at the releases. But the release version (now 3.3) and the master branch version are the same thing? But the Readme suggests downloading phar from the link: Download the file

    And what version does this phar get?

    In fact, a method or property that stores the current version would be very useful. I understand that this introduces problems to maintain it in an actual state, but ways have long been invented for this.

    Reviewed by picasso at 2021-04-06 08:53
  • 13. Identify callable variables

    There are several formats that identify callable vars. Most ancient are traditional PHP callbacks such as [Kint\Kint::class, 'dump'], [$object, 'method'] and function names, then there's the Kint\Kint::dump format, plus Closures and objects with __invoke() methods. All of those can be detected by using is_callable() and hinted as such.

    Here's an example with few callable formats:

    $callables = [
    	[Kint\Kint::class, 'dump'],
    	function() {}
    foreach ($callables as $callable)
    	s($callable, is_callable($callable));
    │ $callable                                                                    │
    array (2) [
        0 => string (9) "Kint\Kint"
        1 => string (4) "dump"
    │ is_callable(...)                                                             │
    boolean true
    Called from .../proba.php:44 [s()]
    │ $callable                                                                    │
    string (15) "Kint\Kint::dump"
    │ is_callable(...)                                                             │
    boolean true
    Called from .../proba.php:44 [s()]
    │ $callable                                                                    │
    string (4) "trim"
    │ is_callable(...)                                                             │
    boolean true
    Called from .../proba.php:44 [s()]
    │ $callable                                                                    │
    Closure (1) (
        public 0 -> Closure (1) RECURSION
    │ is_callable(...)                                                             │
    boolean true
    Called from .../proba.php:44 [s()]
    Reviewed by kktsvetkov at 2020-08-13 07:09
  • 14. Include object id in output

    I often work with similar objects and var_dump with xdebug has the neat feature of outputting the spl_object_id which makes it easy to find out if two outputs belong to the same object or not. Can you include the object id into the output?

    Reviewed by xelax90 at 2020-05-19 09:59
  • 15. Add "copy-to-clipboard" buttons

    It would be very helpful if there would be a copy-to-clipboard button (icon), especially for the "Show access path" textbox. Nowadays the document.execCommand('copy') function is widely supported, so this shouldn't be much of a problem and would help avoid many repetitive steps! Might even be as simple as using double click to copy, although in this case the user would need to know about that functionality first, of course.

    Reviewed by M-Mommsen at 2020-01-07 13:47
  • 16. configuration to have xdebug_get_function_stack

    is it possible to have a configuration which uses xdebug_get_function_stack instead of debug_backtrace ?

    Its useful if you want to print trace inside fatal errors.

    easy to see stack trace inside fatal errors.

    Reviewed by zainengineer at 2018-04-16 05:43
A simple Craft module, inspired by Mildly Geeky's "Kint", to debug Twig within your browser
A simple Craft module, inspired by Mildly Geeky's

A simple Craft module, inspired by Mildly Geeky's "Kint", to debug Twig within your browser

Feb 2, 2022
The ultimate debugging and development tool for ProcessWire
The ultimate debugging and development tool for ProcessWire

Tracy Debugger for ProcessWire The ultimate “swiss army knife” debugging and development tool for the ProcessWire CMF/CMS Integrates and extends Nette

Apr 14, 2022
Xdebug — Step Debugger and Debugging Aid for PHP

Xdebug Xdebug is a debugging tool for PHP. It provides step-debugging and a whole range of development aids, such as stack traces, a code profiler, fe

May 13, 2022
Buggregator is a beautiful, lightweight web server built on Laravel and VueJs that helps debugging your app.
Buggregator is a beautiful, lightweight web server built on Laravel and VueJs that helps debugging your app.

A server for debugging more than just Laravel applications. Buggregator is a beautiful, lightweight web server built on Laravel and VueJs that helps d

May 16, 2022
A collection of helper methods for testing and debugging API endpoints.

Laravel API Test Helpers This is a collection of helper methods for testing and debugging API endpoints. Installation You can install the package via

Apr 16, 2022
Sage - Insightful PHP debugging assistant ☯
 Sage - Insightful PHP debugging assistant ☯

Sage - Insightful PHP debugging assistant ☯ At first glance Sage is just a pretty replacement for var_dump() and debug_backtrace(). However, it's much

May 4, 2022
WordPress debugging made simple.
WordPress debugging made simple.

Loginator Debugging WordPress can sometimes be a pain, our goal is to make it easy, which is why Loginator was built with this in mind. From creating

Feb 12, 2022
A tool to profile mysql queries in php env.
A tool to profile mysql queries in php env.

MysqlQueryProfiler This tool helps you to quickly profile a mysql query in a PHP 7.4+ environnement. You can also compare 2 queries. This image shows

Jul 30, 2021
This package connects a Laravel Octance application with Tideways for PHP Monitoring, Profiling and Exception Tracking.

Tideways Middleware for Laravel Octane This package connects a Laravel Octance application with Tideways for PHP Monitoring, Profiling and Exception T

Jan 6, 2022
Handle PHP errors, dump variables, execute PHP code remotely in Google Chrome

PHP Console server library PHP Console allows you to handle PHP errors & exceptions, dump variables, execute PHP code remotely and many other things u

May 19, 2022
PHP APM (Alternative PHP Monitor)

APM (Alternative PHP Monitor) APM (Alternative PHP Monitor) is a monitoring extension enabling native Application Performance Management (APM) for PHP

May 19, 2022
Zipkin PHP is the official PHP Tracer implementation for Zipkin

Zipkin PHP is the official PHP Tracer implementation for Zipkin, supported by the OpenZipkin community. Installation composer require openz

May 14, 2022
Laravel Dumper - Improve the default output of dump() and dd() in Laravel projects

Laravel Dumper Improve the default output of dump() and dd() in Laravel projects. Improves the default dump behavior for many core Laravel objects, in

May 12, 2022
Debug bar for PHP
Debug bar for PHP

PHP Debug Bar Displays a debug bar in the browser with information from php. No more var_dump() in your code! Features: Generic debug bar Easy to inte

May 11, 2022
PHP Benchmarking framework
PHP Benchmarking framework

PHPBench is a benchmark runner for PHP analogous to PHPUnit but for performance rather than correctness. Features include: Revolutions: Repeat your co

May 22, 2022
The Interactive PHP Debugger

The interactive PHP debugger Implemented as a SAPI module, phpdbg can exert complete control over the environment without impacting the functionality

Apr 26, 2022
Dontbug is a reverse debugger for PHP
Dontbug is a reverse debugger for PHP

Dontbug Debugger Dontbug is a reverse debugger (aka time travel debugger) for PHP. It allows you to record the execution of PHP scripts (in command li

May 8, 2022
PHP Debug Console
PHP Debug Console

PHP Console A web console to try your PHP code into Creating a test file or using php's interactive mode can be a bit cumbersome to try random php sni

May 14, 2022
Php Debugger to run in terminal to debug your code easily.
Php Debugger to run in terminal to debug your code easily.

What is Dephpugger? Dephpugger (read depugger) is an open source lib to make a debug in php direct in terminal, without necessary configure an IDE. Th

Jan 12, 2022