nunomaduro/dig
Dig is a lightweight PHP package by Nuno Maduro that helps you dig into and inspect values in your applications, providing a simple API for clearer debugging and development workflows.
Architecture fit. nunomaduro/dig is developer tooling, not a platform component. It has no customer-facing surface, no request-path footprint, and no bearing on uptime commitments, SLAs, or data contracts. Architecturally it belongs strictly in the require-dev layer alongside VarDumper, Pest, and Collision. The correct framing is a developer-experience line item, evaluated against the cost of the current terminal debug loop — not against the platform roadmap. It addresses a real coverage gap: almost all mature Laravel debugging (Ignition, Telescope, Clockwork, Ray) is browser-request-oriented, while Artisan commands, queue workers, scheduled jobs, ETL/import scripts, and Laravel Zero binaries have no equivalent inspector. Whether that gap is worth closing is the central TPM question, and it is answerable with a one-day spike rather than a design review.
Integration feasibility. Low effort, low ambiguity, cheap to reverse. A pinned composer require --dev, a one-paragraph usage note naming VarDumper as the fallback, a validation pass across the team's actual Docker and SSH setups, and a CI grep gate. Total cost measured in engineer-hours. There is no migration, no data model impact, no API contract, and no coordination with downstream teams. The only prerequisite is confirming the package's actual behavior against source, because the registry metadata is internally inconsistent.
Technical risk. The dominant risks are procedural, not architectural:
vendor/ source, every scoping and use-case claim is speculative. Treat this as a maturity datapoint and a reason to time-box, not to write a spec.require-dev with a pinned constraint.-t, some SSH sessions, and Windows terminals mishandling ANSI/box-drawing. This is a hard blocker where it occurs, not a nuisance.ob_start(), an Artisan command already holding the buffer) can swallow results with no error.files-autoloaded unconditionally per process; a naming clash with Collision, Termwind, or a homegrown debug file produces a dev-only redeclaration fatal.Key questions.
dig() for non-halting terminal probes; dump()/dd()/VarDumper otherwise"), adoption becomes an undocumented local quirk.require-dev hygiene to enforce the boundary — pinned constraints, composer install --no-dev in production builds, grep gate in CI?Stack fit. PHP 8+, Composer, Laravel. No service container, no framework coupling, no runtime dependency to wire. It coexists with — and does not replace — VarDumper, Ignition, Telescope, Clockwork, or Ray. The integration decision is a one-line require-dev entry and a documentation paragraph, nothing more. It is explicitly not a logging strategy, an observability layer, or a profiling substitute, and must be stated as such in writing.
Migration path. There is nothing to migrate. If the org has ad-hoc internal dump wrappers or hand-rolled inspection scripts, this could replace them, but only if it beats the free baseline already installed. The realistic path is: spike on one branch → measure → either adopt as a recommended dev tool or composer remove and delete the wrapper. The reversal cost is hours.
Compatibility. Verify three things before building a habit: the PHP constraint against our supported matrix, the Symfony Console and Termwind constraints against what Laravel already pulls in, and the files autoload entry against any existing global helper definitions. Grep for helper collisions before installing, not after the first dev-only fatal. Confirm the lockfile resolves without shifting any existing dev dependency.
Sequencing.
composer show nunomaduro/dig; read vendor/nunomaduro/dig/ end to end. It is small enough to read in one sitting. Confirm the files autoload entry and version constraints.require-dev on a scratch branch. Test inside the actual Docker image, over remote SSH, and under piped output. Test the output-buffer case. Test coexistence with existing helpers.dig($input, 'raw') → dig($normalized, 'after normalize') → dig($result, 'after transform'). That staged view is the capability dd() structurally cannot provide.debug_probe() that no-ops outside local, add the grep gate to CI, add the one-line fallback note, and list it under "recommended dev tools" — not a mandate. If no-go, remove and record why.Maintenance. Negligible in the near term, unquantifiable in the long term. One maintainer, no support contract, no security-response process, no LTS. The realistic exposure is abandonment: the package stops tracking new PHP or Symfony Console versions and eventually fails to install on the next framework upgrade. Mitigation is a pinned constraint plus a revisit trigger — a stable 1.x, a second maintainer, or a real dependent count — rather than open-ended reliance. A single maintainer is not a blocker for a require-dev convenience; it is a blocker for anything load-bearing.
Support. Internal only. No vendor accountability, no escalation path, no CVE channel. Team support burden is a wiki paragraph and the named fallback sentence. Bus factor for the tool itself is effectively the team's own willingness to maintain a thin wrapper, which is why the wrapper should be small enough to delete in one commit.
Scaling. The tool scales with headcount trivially — it is per-developer, per-machine, with no shared infrastructure. What does not scale is unmanaged usage: unpinned versions across machines, no grep gate, and probes drifting into shared staging or CI logs. Two scaling constraints are worth naming: large payloads (deeply nested arrays and big Eloquent collections render noisily and can stall a constrained terminal — probe the shape, not the whole thing), and interactive-terminal assumptions that do not hold across a heterogeneous fleet of Docker, SSH, CI, and Windows environments.
Failure modes. In rough order of likelihood:
dig() in a console command and it fires in shared staging or a worker job. Mitigation: composer install --no-dev in production builds plus a CI grep gate — enforce the boundary mechanically, not by convention.vendor/ → files entry autoloaded → output buffered or non-TTY → helper collision. That covers most of the surface for a package this small.Ramp-up. Minutes. Labeled probes in a pipeline are self-explanatory to any PHP developer, and the concept maps directly onto dump(). The ramp-up cost is not learning the API — it is learning the boundary: where it applies (terminal surfaces no browser inspector reaches), where it does not (HTTP requests, production, assertions in tests), and what the fallback is. That is the paragraph worth writing, and it is the difference between a tool the team uses deliberately and a local quirk half the team has and half does not.
Overall posture. Low strategic value, low cost, low risk, low maturity, with one unresolved question about what the package actually is. This is an opportunistic, time-boxed trial — not a bet. Approve a spike under require-dev with a pinned version, keep the existing toolchain untouched, and defer any standardization until the spike reports back. Revisit only on a clear trigger; otherwise close it out and keep the free baseline.
How can I help you explore Laravel packages today?