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

Treewalker Laravel Package

lukascivil/treewalker

TreeWalker is a lightweight PHP 8.1+ library for manipulating nested arrays, objects, and JSON strings interchangeably. It offers diffing, recursive walking with edits/deletion, merging, and dynamic key-path get/set/create operations, with configurable array, object, or JSON output.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

Feature bets this unblocks

  • Audit trails and change history for JSON-shaped content — CMS entities, feature-flag payloads, tenant configuration, workflow definitions. getdiff() gives you new / removed / edited buckets with oldvalue / newvalue, which is exactly the shape an "activity log" or "compare versions" UI needs. This is the single highest-value use case: it replaces a hand-rolled recursive diff (typically 3–5 days of engineering plus ongoing edge-case bugs) with a six-method dependency.
  • Admin/ops tooling for integration debugging — when a webhook or third-party payload changes shape, getdiff() turns "why did this break?" into a readable, keyed diff. Good for support-facing internal consoles where polish matters more than RFC compliance.
  • Config and fixture drift detection — structMerge() (first-argument-wins) maps cleanly onto layered configuration: defaults < environment < tenant override. Useful for a "show effective config vs. baseline" screen.
  • Test harness / CI regression gates for API contracts — compare a golden JSON fixture against a live response and fail the build on structural drift. Cheap to add to an existing PHP test pipeline.

Build vs buy

  • Buy (adopt) here. The scope is deliberately narrow, MIT-licensed, composer require-installable, PHP 8.1+, and the entire public surface is six methods. Total replacement cost if it goes stale is roughly 1–3 engineer-days, which is a low enough ceiling to make adoption reversible — this is the key argument for a PM.
  • Do not treat it as infrastructure. No SLA, single maintainer, 73 stars and 0 dependents means "unproven in production at scale," not "safe default."

Roadmap / scoping implications

  • Adopting it pulls in a decision about diff semantics. The README's getdiff() example output appears to label keys present only in the second structure as new while the shown values come from the first — the directionality is ambiguous or the docs are wrong. Before it lands in a customer-facing "what changed" view, someone must nail down the exact semantics with a spike and a conformance test. Budget half a day.
  • Constrain it to internal/back-office surfaces first, then promote to customer-visible diffs once behavior is verified. This keeps the blast radius small if semantics surprise you.
  • It is not a JSON Patch (RFC 6902) or JSON Merge Patch (RFC 7386) implementation, and it does not validate against JSON Schema. If any roadmap item says "standard patch format" or "schema validation," this package is out of scope for that item and you should say so early to avoid a false dependency assumption in planning.

Portfolio note

  • There's a companion JavaScript library (JsonDifference) from the same author. That's mildly attractive if the roadmap includes client-side previews of unsaved changes alongside the server-side diff — consistent semantics across tiers, one vendor relationship.

When to Consider This Package

Adopt when most of these are true

  • Your stack is PHP 8.1+ and Composer-based (Laravel, Symfony, or plain PHP).
  • The data you need to compare is genuinely nested arrays / stdClass objects / JSON strings, and you want to treat all three interchangeably — the single returntype switch (jsonstring | object | array) removes a whole class of serialization glue code from your feature.
  • The requirement is human-readable change reporting, not machine-to-machine patch application. The new/removed/edited shape is presentation-oriented and that's what you want.
  • The workflow involves in-place traversal and edits (walker() passes parent, key, and value by reference) — e.g., redacting PII from a nested payload before logging, or pruning a nested response for a public API.
  • You need dynamic-path get/set — getDynamicallyValue() / setDynamicallyValue() / createDynamicallyObjects() cover the "user maps a field to a.b.c in a settings screen" pattern without writing your own path parser.
  • You can accept vendor-in-your-repo risk and are willing to pin a version, vendor the source, or fork if needed. MIT makes all three trivial.

Look elsewhere when any of these are true

  • You need strict RFC 6902 (JSON Patch) or RFC 7386 (JSON Merge Patch) semantics, or interoperability with another system that emits/consumes those formats. Use a dedicated patch library.
  • You need schema validation (JSON Schema, OpenAPI request/response validation) — different problem, different package.
  • You need typed object hydration into DTOs or Eloquent models rather than loose nested arrays — prefer a serializer/hydrator or Laravel's own resource layer.
  • The diff runs on a hot path or large documents at volume and you need guaranteed algorithmic complexity or streaming. There are no published benchmarks here; measure before you commit to production scale.
  • You require vendor support, an SLA, or a security-response commitment. Zero dependents and a single maintainer means you are the support contract.
  • The requirement is three-way merge or conflict resolution with base/ours/theirs. structMerge() is two-way with first-argument precedence only.
  • Your team is not on PHP 8.1+ and cannot upgrade — hard requirement, no fallback.

Pre-adoption checklist (PM-owned gates)

  1. Semantics spike — confirm getdiff() directionality and what debug / flat-slash-keys actually produce. Write down expected outputs as test fixtures.
  2. Security review — nested-structure walkers on untrusted input invite deep-recursion and reference-cycle DoS. Confirm behavior on cyclic objects and pathological depth, and cap input size at the boundary.
  3. Maintenance posture — pin the exact version; decide now whether you vendor the source. Recent release and modernized CI/codecov are encouraging signals, but plan for the "maintainer disappears" scenario as a normal, cheap-to-absorb event.
  4. Escape hatch — keep usage behind a thin internal adapter (e.g. App\Support\JsonDiff) so the six methods are called from one place. That single decision reduces swap cost to hours.

How to Pitch It (Stakeholders)

For executives

  • It's a small, free (MIT), PHP 8.1+ utility that gives us JSON/array diffing, merging, and dynamic-path access out of the box. It saves roughly one to two sprints of bespoke code in the audit-log and internal-tooling workstreams, and it's already used in a comparable form elsewhere in the author's JavaScript library.
  • Risk is bounded and reversible. The whole package is six methods with no transitive dependency footprint; if it stops being maintained, replacing it in-house is a 1–3 engineer-day task. That is the cheapest possible form of dependency risk.
  • No cost, no lock-in, no licensing review. One decision: vendor the source and wrap it in an internal adapter behind a feature flag on internal tooling first.
  • What it does not solve: standardized patch formats, schema validation, or typed model hydration. If those appear in future requirements, we buy a different tool — this is a complement, not a platform.

For engineering

  • Six methods, PSR-2, PHP 8.1+, unit-tested with Codecov coverage and a modernized CI pipeline. Public surface: getdiff, walker, structMerge, createDynamicallyObjects, getDynamicallyValue, setDynamicallyValue. All accept and return jsonstring | object | array interchangeably, controlled by a constructor flag — that alone removes serialization boilerplate.
  • One known unknown to close before merge: the README's getdiff() example appears to invert the new vs. removed keys relative to the values shown. Treat the docs as suspect and lock behavior down with a conformance test suite in our repo. Also verify cycle handling and recursion depth on adversarial input — this code walks untrusted nested structures.
  • How we'll use it: call it only through a thin internal adapter class, pin the version, and vendor the source so builds are reproducible. That keeps the swap cost near zero and stops the package's API from leaking into our domain code.
  • Where we start: audit/activity diffs and a config "effective vs. baseline" view in the internal admin. If it holds up there, we consider customer-facing change previews. We are explicitly not using it for RFC-compliant patching or schema validation.
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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin