Accept comments and unquoted keys in a JSON config file
Parse a hand-edited config with a lenient JSON dialect, so comments, trailing commas and unquoted keys load instead of failing on one character.
How-to › Section 15
Reading the formats integrations depend on, building parsers from grammars, validating shapes at boundaries, and transforming nested data.
7 guides in 4 topics. Every guide compares its approaches and shows the output its commands printed.
One page per format decision: JSON, JSONC, JSON5, jsonic (unquoted keys, comments, implicit top level, plugins, jsonic-cli), YAML, TOML, INI, CSV (RFC 4180, headers, custom separators, streaming, strict and lenient modes), XML, Markdown, CSS, JSON Lines, Atom and RSS feeds, protobuf IDL and Zon; error positions, streaming large files, when lenient input is the wrong choice.
Parse a hand-edited config with a lenient JSON dialect, so comments, trailing commas and unquoted keys load instead of failing on one character.
Give a lenient parser to files people edit and a strict one to bodies programs send, keep the loaders apart, and let a test refuse a lenient import at the boundary.
Building a parser for your own format: ABNF (RFC 5234) compiled to a rule table with @tabnas/abnf (a state machine as data, not generated parser code), attaching behavior by rule name, extending an existing grammar without forking, inspecting with @tabnas/debug, railroad diagrams, the support libraries (expr, path, directive, hoover, multisource), an LSP and playground for your format, benchmarking with measure, and emitting GBNF for constrained decoding; against peggy, ohm, chevrotain, nearley, ANTLR, tree-sitter, Lark and hand-written recursive descent.
Keep the grammar as plain ABNF, bind behavior to the rule names the compiler assigns, and test that every handler still names a rule and fires after a rename.
Rewrite a left-recursive rule so peggy accepts it, fold the action from the left to keep subtraction left-associative, and compare with ohm-js and nearley.
Runtime validation of inputs, config and SDK responses, and exporting JSON Schema from a validator (this branch owns export, for tool definitions and OpenAPI alike): Zod, Joi, Yup, Valibot, ArkType, io-ts, AJV with JSON Schema, Pydantic, go-playground/validator, and gubu (a schema that looks like the data, Required, Optional, Default, Min, Max, One, Exact, Check, Coerce, Email, Url, Uuid, JSON Schema export, TypeScript and Go).
Write the schema as an example of an accepted value, with constructors for types and literals for defaults, so schema and sample read side by side.
Getting, setting, merging, walking, injecting and transforming nested structures, and flattening API responses for analysis: lodash, ramda, immer, jq, JSONPath, JSON Pointer, json-patch, deepmerge, pandas.json_normalize, and struct (getpath, setpath, merge, walk, inject, transform, validate, flatten, ported to 23 languages at parity).
Layer defaults, file, environment and flags with a deep merge so a later source overrides only the keys it sets, and clone first because merge mutates.
Read a deep value by a path held as a string, so a response mapper is a table of paths rather than a chain of optional accesses written out once per field.
Retries, timeouts, pagination and auth are the same problems in every client. Voxgig generates them from your OpenAPI description, in 23 languages, from one model.