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

Neon Laravel Package

nette/neon

NEON is a human-friendly, YAML-like data serialization format used for Nette configuration files. This package provides a fast, strict parser and dumper for PHP, with support for comments, inheritance, entities and includes, plus detailed error reporting.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit Laravel's configuration layer is opinionated: config/*.php files returning arrays, loaded by Illuminate\Foundation\Bootstrap\LoadConfiguration, flattened into a dot-notation repository, and frozen into a single PHP file by config:cache. nette/neon provides none of those hooks — it is a pure codec (Neon::decode(), Neon::decodeFile(), Neon::encode()) plus an AST/traverser layer added in v3.3.0. Adopting NEON therefore means inserting a parallel format into a pipeline that assumes PHP arrays at load time. That is architecturally possible but it is additive architecture, not a fit: we would be maintaining a translation layer whose only job is to convert a format Laravel does not speak into one it does. The v3.4.x phpDoc and static-analysis improvements remain genuinely useful for the adapter code we would write, and v3.4.9 extends the supported runtime to PHP 8.6 — but none of this changes the equation. They improve the ergonomics of the wrapper and the lifespan of the dependency, not the fit of the package.

Integration feasibility Moderate effort, well-bounded. The realistic shape is ~150–300 LOC: a NeonConfigServiceProvider or bootstrap hook that globs config/*.neon, decodes each with Neon::decodeFile() (atomic since v3.3.4 — meaningful here, since config reads happen concurrently during deploy), and merges into the repository ahead of LoadConfiguration's PHP pass. The non-obvious work is not decoding; it is:

  • Cache coherence — config:cache will silently ignore NEON files unless we override ConfigCacheCommand or pre-merge before the cache is written. This is the single most common way this integration breaks in production. Unchanged by v3.4.9.
  • Precedence rules — PHP config vs. NEON config vs. env() overrides must be defined and documented, or we get divergent behaviour between cached and uncached environments.
  • Type fidelity — v3.4.3 decodes big integers as strings, dates become DateTimeImmutable, and INF/NAN throw (v3.4.1). v3.4.9 adds a subtler rule: a date-shaped literal that is not a valid date (2024-02-30, 2024-13-01) now decodes as a plain string rather than failing. That converts an obvious parse error into a plausible-looking string value, which is a worse failure signature for config. Every one of these is a config-value surprise, and the set is still growing in minor versions.

Also note: the package is not Laravel-discoverable in any meaningful sense — no facade, no config stub, no published provider. Every integration is bespoke and therefore every integration is a snowflake.

Technical risk Elevated, and concentrated in four places:

  1. License — metadata reports NOASSERTION. Nette components are conventionally BSD-3-Clause, but a TPM cannot approve a production dependency on convention. Legal sign-off is a hard gate before any code is written. This alone can stall the initiative for weeks. Nothing in v3.4.9 touches this.
  2. BC breaks in minor versions — the pattern now has a fourth data point: v3.2.0 dropped non-UTF-8 mode, v3.3.0 rewrote the parser and generated an AST, v3.4.0 removed on/off syntax and raised the floor to PHP 8.0, and v3.4.9 reserves the !!chain entity name and rejects it in input. These are disciplined, well-documented breaks, but they are breaks, and a config loader sits on the critical boot path. Any of them becomes an outage class for us. The v3.4.9 item is low-probability for our own configs; the pattern is the risk, not the specific keyword.
  3. Blast radius — a NEON parse failure happens during application bootstrap, before the exception handler and logger are reliably wired. Mitigation requires wrapping every decode in a try/catch that degrades to a clear, non-fatal error. Note that v3.4.9 narrows this surface slightly (invalid dates no longer throw) while simultaneously widening the silent-drift surface — the trade is not a net reduction in risk.
  4. Data-quality caveat on the input metrics — "Dependents: 0" is almost certainly wrong; NEON is a foundational dependency of nette/di, nette/bootstrap, and the wider Nette framework. I would not use the dependent count from this dataset as an adoption signal in either direction, and I would flag the opportunity score of 47 as low-confidence.

Key questions

  • What is the forcing function? Is there an existing NEON corpus we must consume (a Nette service we integrate with, an acquired codebase, a vendor contract mandating NEON)? Absent that, this is a solution seeking a problem, and the answer is no.
  • Who owns the adapter? A single-team, single-purpose loader with no upstream is fine; a shared platform component with no owner is how boot-path incidents happen.
  • Is the value human-authored config, or machine exchange? If the goal is readability for humans editing complex nested config, NEON earns its place. If the goal is interop, JSON and YAML already win on tooling.
  • Can we accept PHP 8.0+ and full UTF-8 strictness across all environments? (Ceiling is now 8.6, which is helpful for our upgrade roadmap; the floor is unchanged.)
  • Does legal accept the license as-is, or do we need an alternative?
  • Do any of our existing NEON documents use !!chain, or rely on invalid dates raising an error? Both behaviours changed in v3.4.9 and both should be grepped before any upgrade.

Integration Approach

Stack fit Poor-to-neutral. There is no first-party Laravel or Symfony bridge; NEON's natural home is Nette's DI container, where NEON is the native config syntax. In Laravel we would be a guest in someone else's house in both directions: NEON is foreign to Laravel, and Laravel's config conventions are foreign to NEON's ecosystem. The compensating factor is that the package is small, dependency-light, and has a clean, stable public surface (Neon::decode/decodeFile/encode plus the AST classes) — so the adapter surface we must pin is narrow. v3.4.9 does not change the public surface; it changes decode behaviour at the edges.

Migration path Incremental and reversible, which is the main argument for proceeding at all:

  1. Read-only pilot — introduce the loader behind a feature flag for a single non-critical config domain (e.g., feature flags or an external service definition). PHP configs remain authoritative; NEON is additive.
  2. Parity harness — dual-load the same domain from PHP and NEON and assert deep equality in CI. This is the gate that catches type-fidelity drift. v3.4.9 raises the value of this control: a malformed date now yields a string instead of an error, so the harness must include date-shaped fixtures (2024-02-30, 2024-13-01) alongside the big-int and INF/NAN cases.
  3. Promote per-domain — move domains one at a time, never all at once, and never config/app.php or config/database.php first.
  4. Exit ramp — because NEON decodes to plain arrays, reverting a domain means writing the array back out as PHP. Cheap. Preserve that property deliberately: never let NEON-specific AST objects leak past the loader boundary.

Compatibility

  • PHP: pin to the v3.4.x line; v3.4.9 extends support to PHP 8.6, so the ceiling is no longer a constraint on our upgrade roadmap. The floor still needs verifying against our oldest supported PHP image, since v3.4.0 raised requirements and v3.4.4/v3.4.5 added 8.4/8.5 support incrementally.
  • Laravel: config:cache is the compatibility hotspot. Treat cache-aware loading as a first-class requirement, not a follow-up ticket.
  • Static analysis: the v3.4.8 phpDoc precision is a real benefit — our adapter will be fully typed against it, so PHPStan/Psalm will catch misuse. Budget for the baseline noise this introduces on first run.
  • Tooling: adopt the bundled neon-lint (v3.3.1+) in CI so malformed NEON fails in the pipeline rather than at boot. Pin the linter to the same version as the runtime, and re-lint on every bump — v3.4.9's !!chain reservation is exactly the class of change a linter catches and a code review does not.

Sequencing Legal/license clearance → spike (2–3 days: loader + config:cache interaction + parity harness) → go/no-go on the spike → pilot domain behind a flag → parity in CI → per-domain promotion → deprecate PHP equivalent once a domain has run clean for a full release cycle. The spike must explicitly prove the config:cache path before any production commitment; that is the decisive experiment and it is cheap to run. Add one task to the spike: audit any candidate NEON corpus for !!chain usage and for invalid-date literals that previously failed loudly.


Operational Impact

Maintenance The package itself is low-maintenance — it is mature, actively released (v3.4.8 shipped 2026-05-11 and v3.4.9 has already followed with PHP 8.6 support), and has a well-kept changelog. The release cadence is a mild negative: two releases inside the review window, one of which is a behavioural BC break, which means our pinned-version bump is not a trivial chore. The maintenance cost sits almost entirely on our adapter, which is bespoke, has no upstream, and must track the package's minor-version BC breaks. Budget realistically: a few days per year for version bumps plus whatever the adapter's owner costs — and treat each bump as a code change requiring the parity suite, not a lockfile edit. If no team will own it, that is a stronger signal against adoption than any technical concern here.

Support Support surface is a public GitHub repository plus documentation and release notes — no commercial backing, no SLA. That is normal and acceptable for a library of this size and stability, but it means boot-path questions get answered by us, not by a vendor. Internal runbook (what a NEON parse failure looks like, how to triage, how to roll back a domain) is a prerequisite, not documentation debt.

Scaling Effectively free. Decoding is per-request only if we decode per-request — and we should not: decode once at boot and rely on config:cache, exactly as Laravel does for PHP configs. The package is designed for speed with minimal dependencies; parse cost is not a scaling concern. The scaling concern is cognitive: every engineer who touches config must now know two formats, and every new hire must learn NEON's block-array and multiline-string syntax to read a config file. That is a permanent, compounding tax across the team in exchange for a one-time readability gain on the files themselves.

Failure modes

  • Boot-time fatal — malformed NEON, an unsupported construct after an upgrade (e.g. a !!chain usage that v3.4.9 rejects), or an invalid UTF-8 byte (encoder replaces these with U+FFFD as of v3.4.7; the decoder is strict) takes the app down before logging is reliable. Wrap and degrade.
  • Cache divergence — cached config silently excludes NEON changes. Highest-probability incident; detect with a startup assertion comparing file mtimes against the cache timestamp.
  • Silent type drift — big ints arriving as strings, dates as DateTimeImmutable, and as of v3.4.9 invalid dates arriving as ordinary strings, breaking downstream consumers that expect exact types or that previously depended on the parse error as a guardrail. The parity harness, extended with date-shaped fixtures, is the control. This is the failure mode v3.4.9 most affects.
  • Upgrade-induced syntax break — a minor bump rejects a construct we use (as v3.4.0 did with on/off, and v3.4.9 did with !!chain). Mitigate with neon-lint in CI pinned to the target version, upgraded deliberately rather than automatically.
  • License finding post-adoption — a NOASSERTION flag discovered after code is in production is the most expensive failure mode on this list and the cheapest to avoid.

Ramp-up Small but non-zero. Engineers need perhaps an hour with the syntax and the docs to read and edit NEON confidently; the block-array and """ multiline conventions are the only genuinely unfamiliar parts. The larger ramp-up cost is organisational: reviewing config PRs now requires a second mental parser, and the "just read config/database.php" reflex no longer works uniformly.

TPM recommendation Conditional no-go, with a narrow yes — unchanged in direction by v3.4.9. Absent a concrete forcing function — an existing NEON corpus, a Nette-based partner system, or an acquired codebase — the value is readability on configs most engineers already read fine, purchased with a bespoke boot-path component, a permanent two-format tax, and an unresolved license question. Do not adopt for greenfield. The v3.4.9 release does not create a forcing function; it marginally improves the dependency's lifespan (PHP 8.6) while marginally worsening the failure characteristics (invalid dates degrade silently, another minor-version input break). If a forcing function exists, run the 2–3 day spike against config:cache and the parity harness, clear legal first, audit the corpus for !!chain and date-shaped literals, and scope the rollout to the domains that actually need NEON rather than the whole config/ directory.

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.
tobya/saloonfire
kjmtrue/laravel-debugbar
hexincorp/debugbar
razorbacks/laravel-shibboleth
adilazhari/laravel-idempotency
mamitech/laravel-slow-query-log
mamitech/laravel-http-logger
medeirosrafael/docxmustache
webdevlabs/phreak
vis/log-envelope
digitickets/lalit
acacha/names
scool/foundation
frankkessler/guzzle-oauth2-middleware
delatbabel/site-config
delatbabel/applog
eusonlito/laravel-gettext
henzeb/housepedia-intelligence-laravel
aliqsm/laravel-authkit
itsjustvita/laravel-wp-migrator