Repository navigation
NEON 4 parses a file into a lossless syntax tree in which every comment and every space has its place, so you can edit a configuration and the diff shows only your change. Decoding and encoding stay as they were: Neon::decode() gives the same values as 3.4.
✨ New Features
- Lossless parsing –
Neon::parse($text)->print() === $textholds for any input NEON accepts - Format-preserving editing –
setValue(),addItem()andremoveItem()change only the tokens they edit:0x0CEAstays hexadecimal,yesbecomesno, a new key is indented like its siblings, and a removed item takes its comment along. A refused edit changes nothing at all, so installers, admin panels and AI agents can rewriteconfig.neonsafely - A navigable tree – nodes know their parent, their comments and their position (line, column, offset);
find(),findAncestor(), siblings, and a public Traverser that can replace and remove nodes on the walk - Evaluator – subclass it to turn literals, strings or entities into your own values, such as constants or parameters, the way the Nette DI container reads its configuration
- Neon::encode() accepts a closure as
$blockModeto decide per array whether it is written as a block, e.g.fn($v, $path) => !$pathfor the first level only, and writes floats in the shortest form that reads back exactly - Exception carries the position of the problem as an object and the bare message via
getDescription() - neon-lint reports one line per finding,
--jsonfor tools and--checkto verify that a file prints back byte for byte; an AI agent can run it after saving a.neonfile - Runnable examples with their real output document the whole API
- The format, the tree and the editing semantics follow a language-neutral specification shared with the JavaScript implementation @nette/neon
💥 Breaking Changes
- Requires PHP 8.4 or newer and the
mbstringextension - The tree API is new: Neon::parse() returns a
Nodes\DocumentNode, and the classesDecoder,Node\*and the oldTraverserare gone. Code that walked the old nodes moves to the new tree, see examples/tree - Neon::encode() throws
Nette\Neon\Exceptionfor a string that is not valid UTF-8 instead of replacing it with U+FFFD; its errors now name the path to the value - Some error messages are more precise; code that matches their text may need an update
- neon-lint has a new command-line contract:
--debugis gone, and a failure of the tool itself exits with 2 Neon::BLOCKandNeon::CHAINare deprecated, useblockMode: trueandNeon::Chain