mindplay/readable
mindplay/readable renders any PHP value—arrays, objects, and scalars—as clean, human-readable, valid PHP-like code that's easy to read and diff, with optional parsing back into values. Handy for debugging, logging, snapshots, and config files.
Build vs. buy for a micro-utility. mindplay/readable is a single-purpose formatter: given any PHP value or type, it returns a human-readable string. That makes it a classic "should we even own this code?" decision rather than an architecture decision. The package is small enough (a handful of functions) that the realistic options are: (a) add it as a require-dev dependency, (b) vendor/copy the source into app/Support, or (c) skip it and lean on symfony/var-dumper, which Laravel already ships. Frame the decision as cost-of-ownership, not capability.
Developer-experience / debuggability investments. It supports the recurring roadmap question "how much do we invest in making failures legible?" Concrete features it enables:
Expected int, got string or array(3) {...} instead of Object of class Foo could not be converted.Log::error('...', ['payload' => readable($payload)]) produces searchable, single-line entries rather than [object] or nested array noise.Roadmap placement and priority. This is a low-priority DX papercut fix, not a differentiator. It should be scoped as a half-day chore inside an existing DX or observability ticket, never as its own initiative. The signal to weigh: 10 stars, 0 dependents, and a 0.11 composite score mean the ecosystem has not validated this package — treat adoption as "accepting a small maintenance liability," not "gaining leverage."
A guardrail decision on production error surfaces. Deciding whether human-readable formatting is dev-only or user-visible is the real product call. readable() output is diagnostic, not presentable — it will leak class names, internal structure, and parameter shapes into API responses if used carelessly. Use it behind APP_DEBUG, in logs, and in exceptions that are rendered as 500s, never in 4xx validation payloads.
What it explicitly does not decide. It is not an error-tracking strategy, not a replacement for structured logging (Monolog/PSR-3 processors), not a serializer, and not a substitute for symfony/var-dumper in local development. If a stakeholder expects it to solve observability, redirect them.
Adopt when:
var_dump/dump output is unusable and a full dumper is too heavy.require-dev or debug-gated code paths, so a low-adoption dependency cannot affect production behavior or the runtime dependency graph.Look elsewhere when:
dump/dd and symfony/var-dumper; you already have them.Adoption gate for a PM to set: require a named owner, a vendoring-or-pinning decision, and confirmation the dependency stays out of require. If any of those can't be answered in a ten-minute conversation, the correct decision is to skip it — the expected value is small and the cost of a stalled dependency is not.
For executives (one paragraph): We're evaluating a small, free utility that improves how our PHP errors and logs read. It won't move revenue or customer metrics; the value is engineering velocity — faster diagnosis when things break. Cost is near zero (no licensing, dev-only dependency, half a day to integrate), and the main risk is that it's a single-maintainer project with minimal community adoption. Recommendation: adopt it only in debug and logging paths, pin or vendor the source so an abandoned upstream can't hurt us, and treat it as a nice-to-have bundled into existing DX work rather than a standalone line item.
For engineering leads (bulleted):
Log::error context, console output, and test failure text — exactly the places where dump() is too verbose and json_encode is too opaque.require-dev or behind debug flags; do not let it format anything a customer sees.CliDumper for dev, or a ~100-line internal helper. Either is acceptable — the decision is low-stakes, so don't spend a meeting on it.How can I help you explore Laravel packages today?