comment-json
Parse and stringify JSON with comments, preserving them exactly through modification and re-save.
Repository Health
Technical Analysis
comment-json is a drop-in replacement for the native JSON.parse/JSON.stringify pair that adds first-class support for comments and blank lines inside JSON documents. Where most JSON-with-comments libraries strip everything down to a comment-free object, comment-json parses the source into a normal JavaScript value while tucking every comment and blank line away as symbol properties, so stringify() can reproduce the original formatting after a program edits the parsed data.
This solves a specific pain point for any tool that reads a JSON config file, changes a couple of values programmatically, and writes it back out — VS Code-style settings, tsconfig-style files, or any hand-annotated .jsonc config. The library also ships a CommentArray subclass that keeps comment positions correct through splice, slice, sort, reverse, and other array mutations, plus helper functions (assign, moveComments, removeComments, removeBlankLines) for common comment-manipulation tasks.
What You Get
- Comment-preserving parse/stringify - drop-in replacements for
JSON.parse/JSON.stringifythat retain every line and block comment through a full parse-modify-stringify round trip. CommentArraysubclass - anArrayextension that keeps comments attached to the right index acrosssplice,slice,push,pop,sort,reverse, andconcat.- Symbol-keyed comment storage - comments live on nine well-defined
Symbol.for(...)properties (before,after-prop,after-colon, etc.) so they never collide with real JSON keys or show up inObject.keys(). - Comment utility functions -
assign,moveComments,removeComments, andremoveBlankLinesfor reordering keys, migrating comments between objects, or stripping comments/blank lines on demand. - TypeScript declarations bundled - typed
CommentSymbol/CommentDescriptorhelpers ship in the package itself, no separate@typespackage needed since 2.4.1.
Common Use Cases
- Editing user config files programmatically - a CLI or editor extension needs to bump a version field or add a key to a hand-annotated
.json/.jsoncconfig without wiping out the user’s comments. - Building settings-migration tools - a tool that upgrades an app’s saved settings file across versions while leaving explanatory comments intact.
- Sorting or reorganizing JSON keys - using
assign()to reorder an object’s properties (e.g., alphabetizingpackage.jsonfields) while comments travel with their original key. - Parsing JSONC-style config formats - reading configuration languages that allow comments (similar to
tsconfig.jsonor editorsettings.json) where comments carry real documentation value.
Under The Hood
Architecture
The library follows a small, monolithic module structure organized around three files under src/: parse.js (a recursive-descent parser built on esprima’s tokenizer), stringify.js (a mirror-image serializer), and array.js (the CommentArray class extending native Array), with common.js holding shared symbol constants and predicates. Parsing uses module-level mutable state (current, last, index, tokens, a comments_host stack) rather than a class instance, functioning as a synchronous state machine that walks tokens from esprima.tokenize and threads a comments-host stack through nested object/array parsing so each nested value’s Symbol-keyed comments attach to the correct owning object; stringify.js mirrors this by walking the JS value graph and re-emitting comment text from those same symbols through a process_comments/join/join_content pipeline that manages line-break bookkeeping. There is no plugin layer — the library is a pure function pair plus one Array subclass — so what breaks if the core Symbol-keyed comment-attachment scheme changes is essentially everything: both parse and stringify, and any consumer reading Symbol.for('before:prop')-style properties directly, are tightly coupled to it.
Tech Stack
Runtime dependencies are minimal: esprima for JS/JSON tokenization and array-timsort for the stable sort used by CommentArray.sort() (needed because comment repositioning depends on a predictable index-mapping between old and new order). It is plain CommonJS, targets Node >= 6, and ships hand-written TypeScript declarations (index.d.ts) rather than being authored in TypeScript itself. Dev tooling includes ava as the test runner, nyc for coverage uploaded to Codecov, eslint with a shared config for linting, and typescript used only to typecheck the bundled .d.ts file. CI runs on recent Node versions via GitHub Actions, executing install, lint, test, and a coverage upload; no bundler is needed since the package ships plain JS directly from src/.
Code Quality
Tests live under test/*.test.js using ava, covering parse, stringify, array, move-comments, remove-comments, and remove-blank-lines behavior through large tables of description/source/expected-output/assertion fixtures, backed by JSON fixture files. A dedicated TypeScript test typechecks the bundled .d.ts file itself against real usage. Error handling in the parser is explicit: malformed input throws real SyntaxErrors with line/column metadata attached rather than silently returning null or partial data, and no swallowed errors were found in the core parse/stringify path. Naming is internally consistent (snake_case helpers, camelCase public API) and lint is enforced in CI.
API Design
comment-json’s public surface deliberately mirrors the native JSON object (parse, stringify with the same signatures), which minimizes the learning curve for anyone already using JSON.parse/JSON.stringify — adoption is close to a drop-in swap. Where it differs from a plain JSON library, it does so narrowly and documents each addition (the nine comment-symbol positions, the CommentArray mutation methods, and the small set of helper functions) rather than growing a large surface area, keeping the boilerplate required to start using it close to zero beyond an npm install.
Used by 3 apps in this directory
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
GitButler
Developer Tools · Devops · AI Development
Git, but better — a modern version control client with stacked branches, parallel workflows, unlimited undo, and first-class support for AI-powered development.
Payload CMS
Developer Tools · Blogging · CMS
The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.