Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Krumo Laravel Package

mmucklo/krumo

Krumo is a drop-in replacement for print_r() and var_dump() that renders PHP arrays and objects as collapsible, color-coded DHTML trees. This Composer-ready fork makes debugging nested data easy, showing types, values, and structure at a glance instead of dumping raw text.

Deep Wiki
Context7

Getting Started

Krumo is a standalone PHP class — there is no service provider, no facade, no config file to publish. It renders any PHP value as a collapsible HTML tree (types, lengths, object class/properties, array keys) with per-node expand/collapse.

  1. Install it:
composer require mmucklo/krumo
  1. Make the front-end assets reachable. Krumo's output embeds <link>/<script> tags pointing at a URL you configure, so copy or symlink the package's CSS/JS into the public directory:
cp -r vendor/mmucklo/krumo/resources public/vendor/krumo
  1. Point Krumo at them once, early in the request (a service provider's boot(), or a local-only middleware):
krumo::setDir('/vendor/krumo/');
  1. Dump something:
Route::get('/debug', function () {
    krumo::dump(User::with('posts')->first(), 'user');
});

Where to look first: the main class file (class.krumo.php or similar) for the static API surface and config keys, and the resources/ folder for the assets. The fork's README is the authoritative list of what was added over the long-dead upstream — skim it before assuming upstream behaviour.

First real use case: a throwaway local route (or a if (app()->environment('local')) block in an existing controller) to inspect an Eloquent model with relations, a request payload, or a third-party API response, without spinning up Xdebug.

Implementation Patterns

Gate everything behind the environment. Krumo writes raw HTML straight to the output stream; there is no "off switch" by default.

// AppServiceProvider::boot()
if ($this->app->environment('local')) {
    krumo::setDir('/vendor/krumo/');
}

Optionally add a local-only middleware that calls krumo::disable() when the request expects JSON, so a stray dump never corrupts an API response.

Define a project-local kd() shortcut if you want dump-and-die semantics. Keep the name distinct from Laravel's dd() so you can mix both:

function kd(...$vars) {
    foreach ($vars as $v) { krumo::dump($v); }
    exit;
}

Capture output instead of printing it. Wrapping the call in an output buffer is the reliable way to get Krumo's HTML as a string — useful for writing to a log file, returning it in an AJAX debug endpoint, or attaching it to an exception report:

ob_start();
krumo::dump($payload, 'payload');
$html = ob_get_clean();
Log::debug($html); // or return response($html)

This is also the pattern for debugging AJAX/JSON flows: add a ?debug=1 branch that returns the captured HTML as a text/html response rather than polluting the JSON body.

Label every dump. krumo::dump($var, 'name') puts a title above the tree; when you have five dumps on one page, unlabelled trees are useless.

Dump the shallow shape, not the object. For Eloquent, $model->toArray() or $model->getAttributes() gives a far more readable tree than the model instance, whose protected properties and loaded-relation graph are noisy. Use the instance only when you specifically need to see relation loading state.

Configure per use case, not globally. krumo::setConfig([...]) accepts an array and its effect is static/per-request, so it's safe to change it mid-request — e.g. tighter sorting or display settings right before a specific dump, then reset. Treat the config as write-once-per-script unless you actually need variation.

Asset route alternative. If you don't want files in public/, register a tiny route that serves the CSS/JS from the vendor path and point setDir() at it. This keeps deploys clean but adds a route; either is fine.

Debug endpoint pattern for tinker-shy teammates. A single /__debug route guarded by local + an allow-list of query params (model class, ID, relation) gets 90% of the value of Krumo without anyone needing a shell. Krumo is the rendering layer; the route is the ergonomics.

Gotchas and Tips

  • krumo is a lowercase class name and it defines a global krumo() function. It's classic PHP, autoloaded via classmap, not PSR-4. Don't try to namespace it, and don't define your own krumo() helper.
  • Never define a global dump() wrapper. Laravel already ships Symfony's VarDumper dump(); shadowing or redeclaring it produces confusing "cannot redeclare" fatals depending on load order. Use krumo::dump() explicitly or your own kd().
  • No dd() equivalent. Krumo prints and returns; it does not halt. Forgetting exit after a dump means the rest of the page renders and you may be reading a half-built response.
  • Broken assets look like broken Krumo. If setDir() is unset or wrong, you get an unstyled nested list that never expands — the data is all there, just collapsed and ugly. Check the browser network tab for 404s on krumo.css/krumo.js first, before suspecting the data.
  • Output corruption is the main production risk. A dump inside a JSON response, a redirect, or after headers are sent will either poison the payload or trigger "headers already sent". This is the entire argument for environment gating plus a JSON-aware disable().
  • Huge or recursive structures will hang the page. Eloquent models with circular relations, $GLOBALS, framework container internals — dump the toArray()/getAttributes() slice instead of the live object graph. If you must dump the object, do it on a small fixture, not on app().
  • Static, per-process state. disable()/enable() and setDir()/setConfig() persist for the whole request (and across requests in a long-running worker like Octane). If you disable Krumo for a JSON route, remember the effect can leak within that worker — reset it or rely on per-request bootstrap in boot().
  • Values are HTML-escaped, but the surrounding page isn't yours. Dumping inside a Blade view prints fine (it's raw HTML), but dumping inside a <textarea>, an attribute, or between tags in a table cell will produce invalid markup.
  • This fork exists because upstream stalled. PHP 7.4/8.x and modern syntax fixes are the point; pinning mmucklo/krumo and ignoring the original krumo package is the correct choice. If something breaks on a new PHP version, the fork's issue tracker — not upstream — is where the fix lands.
  • License is LGPL-2.1. Using it as a dev dependency is unproblematic. Modifying the library itself and distributing your app means you should be prepared to share those modifications to Krumo; keeping it in require-dev and out of production builds sidesteps the question entirely.
  • Add it to require-dev and to a pre-commit grep. grep -rn "krumo::dump\|krumo(" app/ routes/ in a git hook is a cheap way to stop debug dumps reaching review.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels