hjson-js

A human-friendly JSON superset with comments, quoteless strings, and optional commas — parse and stringify config files without sacrificing readability.

Library
npm
v3.2.2
432stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
37/100Needs Attention
Development Activity0
Maintenance0
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
63/100Good
Architecture60
Code Quality55
Innovation55
Learning Curve80

Hjson is the JavaScript reference implementation of the Hjson syntax — a relaxed superset of JSON designed to be edited by humans rather than only generated by machines. It extends standard JSON parsing to accept # and ////* */ comments, quoteless (bare) strings, optional trailing commas, and multiline triple-quoted strings, while still stringifying back to valid JSON or Hjson on demand.

The library ships both a Node.js/browser API (Hjson.parse / Hjson.stringify) and a standalone hjson CLI for converting files between JSON and Hjson from the command line. A round-trip mode (Hjson.rt) preserves whitespace and comments when a config file is parsed, edited programmatically, and written back out, which is the library’s main draw for tooling that needs to modify a user’s config without clobbering their annotations. Optional domain-specific formats (DSF) add support for values like Inf/NaN and ISO dates that plain JSON can’t represent.

What You Get

  • A drop-in Hjson.parse/Hjson.stringify API that reads/writes both plain JSON and the more permissive Hjson syntax
  • A require-config hook (require('hjson/lib/require-config')) that lets Node.js require() a .hjson file directly
  • Round-trip mode (Hjson.rt) that preserves comments and whitespace when a config is parsed, mutated, and re-serialized
  • A standalone hjson command-line tool for converting files between JSON and Hjson, with colorized terminal output
  • Configurable stringify output — quote styles, indentation, comma separators, condensed single-line objects/arrays, and custom EOL
  • Optional domain-specific formats (DSF) for Inf/NaN/-0 math values and ISO date parsing beyond what plain JSON supports

Common Use Cases

  • Loading application config files that need to stay human-editable and support inline comments explaining each setting
  • Building a CLI or build-tool step that converts a repo’s .json files to commented .hjson (or back) for editing
  • Programmatically updating one field in a user’s existing Hjson config while preserving their comments and formatting
  • Accepting a more forgiving input format (missing commas, unquoted strings) from end users or config authors
  • Bundling Hjson support into an Electron or browser app via the prebuilt bundle/hjson.min.js UMD build

Under The Hood

Architecture The package is composed of small, single-purpose modules under lib/hjson-parse.js, hjson-stringify.js, hjson-comments.js, hjson-common.js, and hjson-dsf.js — wired together by hjson.js, which acts as a thin composition root exposing parse, stringify, rt (round-trip), dsf, and comments. Both parser and stringifier are hand-written, character-by-character state machines (a closure-scoped at/ch cursor with next()/peek()) rather than built on a parser-generator or regex-based tokenizer, which keeps the runtime dependency-free but means the two directions (parse vs. stringify) each reimplement their own traversal logic rather than sharing an intermediate AST. Comment preservation is bolted on separately: parsed values get a non-enumerable __COMMENTS__ property (via hjson-common.createComment) that hjson-comments.js can later extract into a portable comment tree or merge back onto a fresh object, which is what makes the Hjson.rt round-trip mode work without a full CST. There is no dependency-injection or plugin architecture beyond the DSF (domain-specific format) hook, which lets math/hex/date extensions register additional parse/stringify handlers without touching the core scanner.

Tech Stack The runtime has zero dependencies — pure ES5-era JavaScript ("use strict", function-based modules, no ES6 syntax) that runs unmodified in old Node.js versions and browsers alike (the .travis.yml matrix tests Node 0.10 through 8). A single Node built-in (os.EOL) is used for line-ending defaults and guarded so it degrades gracefully in a browser bundle. devDependencies only cover the build pipeline: browserify/browserify-header to produce the UMD bundle/hjson.js, uglify-js to minify it, and eslint for linting; there is no TypeScript, no bundler for the library itself, and no test runner beyond a hand-rolled script. The CLI (bin/hjson) is a thin Node script with manual argv parsing (no commander/yargs).

Code Quality Tests live in test/test.js, a ~90-line hand-written runner (not Jest/Mocha/etc.) that reads a testlist.txt fixture list under test/assets/, round-trips each fixture through parse and stringify, and diffs the output against expected _result.json/_result.hjson files across four CRLF/LF permutations — a solid fixture-driven regression suite for a project this size, though it has no coverage reporting and no CI badge currently passing (the linked Travis CI service is defunct). There are no type annotations (plain JS, no JSDoc types, no TypeScript defs shipped), and error handling is done via thrown Error/SyntaxError objects with hand-built line/column context (error() in hjson-parse.js) rather than a structured error type. Naming is consistent and the modules are small and readable, but the character-scanning code relies on shared mutable closure state (at, ch) which is a common pattern for hand-written parsers but harder to unit-test in isolation than a functional/immutable parser combinator style.

What Makes It Unique Hjson’s distinguishing technical choice is treating comment/whitespace preservation as a first-class, opt-in mode (keepWsc) rather than an afterthought — most JSON-superset parsers (JSON5, JSONC) discard comments on parse, but Hjson’s rt (round-trip) API and separate hjson-comments.js extraction/merge functions let a program parse a human-edited config, mutate specific fields programmatically, and re-serialize it with the original comments and formatting intact. Its quoteless-string grammar (bare text up to end-of-line, tf/nn/null keyword detection, DSF-extensible) is also more permissive than JSON5’s, prioritizing what a non-technical human would naturally type in a config file over strict grammar minimalism.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search