cerbero/json-parser
A PHP/Laravel package for parsing large JSON files efficiently with low memory. Use JSONPath-style queries to extract exactly the data you need, stream huge documents without loading them fully, and integrate cleanly into Laravel apps for imports, APIs, and data processing.
Architecture fit. cerbero/json-parser is a pull (streaming) JSON parser, not a document parser. Its value proposition is bounded memory: it walks a stream token-by-token instead of materializing the whole document via json_decode, so it fits the ingestion/ETL edge of the architecture — third-party exports, webhook payloads, S3/Flysystem objects, and Illuminate\Http\Client\Response bodies — rather than the domain or presentation layers. In a Laravel codebase it belongs in the infrastructure layer, wrapped behind a small internal interface (e.g., LargeJsonReader) so the rest of the application is not coupled to a niche, single-maintainer library. It is explicitly not a replacement for native JSON handling: for payloads under a few MB, json_decode is faster (C implementation), simpler, and already trusted. The architectural decision to evaluate is therefore narrow and testable: "do we have a class of payloads that must not be fully buffered?"
Integration feasibility. Low friction mechanically. Composer install, MIT license, no transitive dependencies, no framework coupling (Laravel helpers are optional conveniences), small public API surface (parse a source, address nodes via JSON Pointer/Path, then get/first/last/each/collect/chunk). A capable engineer can produce a working proof of concept in a day. The real feasibility question is verification work, not installation: confirm the package's PHP constraint covers the target runtime (it was last released 2023-08-19, so PHP 8.3/8.4 behavior, deprecations, and Laravel HTTP client compatibility must be tested, not assumed), and confirm the source types actually in scope (string, resource, PSR-7 stream, HTTP response) map cleanly to current code paths.
Technical risk.
json_decode (number precision, deep nesting, whitespace/BOM, escaped Unicode, partial-read behavior on truncated streams). These are the bugs that reach production.Key questions. What payload sizes and sources are genuinely in scope, and what is the measured memory/time delta versus json_decode on real samples? Which PHP and Laravel versions must be supported, and does the package pass the test suite on them? Who owns the internal wrapper and the fork-if-abandoned contingency? Is streaming actually necessary, or would vendor-side pagination/chunked endpoints remove the need entirely?
Stack fit. Composer/PHP with no runtime dependencies, framework-agnostic, and compatible with PSR-7 streams and Laravel's HTTP client responses. It slots into queue jobs, artisan commands, and HTTP-client service classes; it has no bearing on Blade, Eloquent, or the HTTP kernel. Good fit for Laravel's queue-worker model, where per-worker memory ceilings make bounded parsing directly valuable.
Migration path. Do not do a broad replacement. Introduce it for one new or clearly problematic ingestion path, behind an internal adapter interface with contract tests. Keep json_decode as the default everywhere else. The adapter boundary is the migration insurance policy: if the package stalls, swapping in a maintained alternative (or a native stream-filter approach) is a single class change. Vendor the source under a pinned version if the fork contingency is real.
Compatibility. Validate in the spike: PHP constraint vs. target runtime (including 8.4 deprecation noise), behavior on all source types in scope, and parity tests against json_decode on a corpus of production-shaped payloads (deep nesting, large integers, UTF-8/BOM, malformed truncation). Confirm no reliance on ext-json where the host environment is constrained.
Sequencing.
Maintenance. Low churn by design (zero deps, small codebase) but also low activity: plan on pinned versions, a documented fork policy, and periodic review of the upstream repo and PHP-version compatibility. Budget a small recurring allotment rather than assuming passive safety.
Support. No commercial support; community issues only. Mitigate by keeping the wrapper thin and the package's code readable enough that the owning team can debug it directly. Internal documentation of supported patterns is the real support layer.
Scaling. Memory scales with nesting depth and chunk size, not document size — the core win for horizontally scaled queue workers. CPU is the trade-off: interpreted PHP parsing is slower per byte than native json_decode, so this is the wrong tool for high-volume small payloads and a reasonable one for large, occasional, or unbounded streams. Parallelism is achieved at the worker level; there is no intra-stream concurrency.
Failure modes. Truncated or malformed JSON, mid-stream network disconnects, non-seekable sources, oversized scalar values, encoding issues, and unclosed handles. Design for these explicitly: idempotent jobs, bounded retries, hard input-size and wall-clock limits, and structured logging on parse failure. Treat a parse error as a data-quality signal, not just an exception.
Ramp-up. The API is small, so a mid-level engineer is productive in roughly half a day to a day; the actual learning curve is the pull-parsing mental model and JSON Pointer addressing, plus the discipline of not buffering results into memory downstream (a ->collect() on a huge node defeats the purpose). Pair the rollout with internal examples and a short review checklist. Overall this is a good, low-cost, high-leverage tool for a specific ingestion problem — adopt it deliberately and narrowly, not as a general JSON replacement.
How can I help you explore Laravel packages today?