DEV Community

Chris Cook
Chris Cook

Posted on • Edited on • Originally published at zirkelc.dev

How To Use JSON with Comments for Configs

Most of the tools we use daily in the Node.js ecosystem utilize config files that support various formats such as .js/cjs/mjs, .yaml/toml, or .json. I usually prefer to work with simple text formats like JSON over JavaScript because it spares me the hassle of navigating the ESM vs. CJS battle for the correct file extension and export specifier. Even better, if the config publishes a JSON schema, then you get type safety without having to rely on JSDoc or TypeScript types.

The biggest downside to using JSON for config files is, in my opinion, its lack of support for comments. I want to explain why I enabled a certain feature or disabled a certain rule. I know most tools still accept comments in JSON files because they don't use the native JSON.parse function, which errors on comments, but instead use custom packages like JSON5 that support comments.

My new go-to linter, Biome.js, solves this by accepting a biome.jsonc (JSON with Comments) as a config file. However, other build tools like Turbo only accept a plain turbo.json file, even though they allow for comments embedded in the JSON. When you open this file in VSCode, you will encounter numerous errors because of the comments.

Image description

VSCode opens this file based on its file extension in JSON language mode (see the language indicator in the bottom bar). Interestingly, if you open a tsconfig.json, you will notice that VSCode interprets this file as JSON with Comments even if it doesn't contain any comments.

Image description

VSCode allows you to associate a file name with a certain language. These file associations are defined in the .vscode/settings.json file:



// .vscode/settings.json
{
  "files.associations": {
    "turbo.json": "jsonc"
  }
}


Enter fullscreen mode Exit fullscreen mode

Now opening the turbo.json file again will automatically use the right language (JSON with Comments). However, keep in mind that you should verify if your tool actually supports JSON with comments. For example, Node.js doesn't support comments in package.json, and doing so will break your package and potentially all dependent packages.

Top comments (21)

Collapse
 
goodevilgenius profile image
Dan Jones

What I like to do is add comments as unused keys. For example:

{
  "key":"value",
  "__key": "Use this field to specify the thing"
}
Enter fullscreen mode Exit fullscreen mode

This works everywhere. It's valid JSON, and the __key field will just be ignored.

Collapse
 
elsyng profile image
Ellis • Edited

No syntax highlighting support for that, though. 🙂

Comments are usually highlighted in a different colour etc., which is not just cosmetics, but makes the code easier and safer to maintain.

Collapse
 
zirkelc profile image
Chris Cook

That’s a good idea. Not sure if it works if the JSON has a schema definition ($chema)? Might show a warning in that case.

Collapse
 
fyodorio profile image
Fyodor

TIL, interesting option 👍

Node.js doesn't support comments in package.json, and doing so will break your package

Do other runtimes (deno/bun) support that?

Collapse
 
zirkelc profile image
Chris Cook

Yes, Bun supports it: https://x.com/jarredsumner/status/1779997854075171184?s=46&t=u_k6xWMtc9OewtjYxfQcEg

There was a big fuss about it, because Node.js does not support and it will likely break other packages if they install such a package. I didn’t try it myself, so not sure if you can even publish such a package to npm.

Collapse
 
radandevist profile image
Andrianarisoa Daniel

I do like the following pattern in package.json:

 ''// === my comment": "=== //"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ricardo_pinto_506b9c1d4bf profile image
Ricardo Pinto

I do use a lot of comments, both in package.json and JSON config files.
Example:

{
"scripts": {
"---------- RUNNING ON IOS ---------": "",
"ios": "expo run:ios --scheme Debug",
}
}

Collapse
 
johnfx profile image
Johnfx

I've never needed comments embedded in my JSON because I document the JSON. I also document changes to the JSON when I'm checking in changes so someone looking at the commit will understand why it was changed.

Maybe more people need to learn how to fully use the tools they have instead of complaining about the limitations based only on what they already know how to do or the habits they already have.

Collapse
 
vincent_huss_271b29c3eb25 profile image
Vincent Huss • Edited

Your setup sounds heavy and while it's great and is probably what should be done for serious project,
It is unrealistic to think developers will always setup something like that, especially if the project is smaller in scale and doesn't justify this kind of heavy initial investment, Therefore, offering a simple and intuitive solution is a must.

Also, with your solution it seems that you're externalising comments and explanations,
That's a tradeoff, nothing beats having them right next to the portion of code that you.re commenting. (And I don't think doing a huge amount of commit so you can place a commit comment on each line you want would be a good solution)

Collapse
 
cbreezier profile image
Leo Huang

This is a silly take.

Where do you document your code? Do you also believe comments in code are unnecessary because you have some documentation elsewhere, perhaps in git commits?

As an aside, git commits aren't a great place to document why something was done. They should be short enough to just cover the what, and leave the why to comments or a reference to an external issue/ticketing system.

Collapse
 
johnfx profile image
Johnfx

The attributes in all configuration file are in application documentation, where everyone has access to it. It is very detailed when necessary and makes the JSON file much more legible as most attribute names are already somewhat obvious. Everyone knows where all of the documentation is so it's accessible. And it's part of the code review process to ensure it's maintained

The ticket system documents the what needed not the details. Every change should have some corresponding, detailed commit log so anyone scanning for specific changes can not only find the change but also why it was changed, asking with a reference to the ticket so they can find out why if needed. Some companies require very detailed commit logs for this very reason.

Or you can fly by the seat of your pants and hope and pray everyone comments and then whine and complain that your kludge is messing things up instead of using the tools you already have for their explicit purpose. Go ahead and spend hours trying to get some unsupported freeware to work hoping it doesn't go the way of the dodo one day and doesn't break with future software updates

Separate your documentation from your code. There is no such thing as self documenting code.

Only lazy programmers that use it as an excuse..

Thread Thread
 
cgatian profile image
Chaz Gatian • Edited

Terrible advice. I hope I never work with you.

Collapse
 
elsyng profile image
Ellis

Agreed, in the sense: it is much better to write self-documenting code, ie the key and variable names should be self-explanatory as much as possible.

  1. In any kind of code when you find yourself needing to add comments, then you should actually take a step back and re-examine the code. Comments are a very good sign that the code or naming needs improvement.

  2. They say: a code document (of any sort) is old as soon it is written. It conflicts with the principle of single source of truth. It happens often that the code changes and the comments/documents don't get updated. In the end we don't trust, and we ignore, the comments (or the documentation). And they just become clutter.

But interesting discussion nevertheless.

Collapse
 
jemiloii profile image
Brian Jemilo II

You are doing it very wrong. It's intentional to not have comments in json. They didn't want weird compilers to do special things to json. Either use more descriptive property names or use a JavaScript file and export an object. If json allowed for comments, JavaScript probably wouldn't have been the powerhouse it is today. Java would have handle it different, python would have did things differently, grunt/webpack/gulp would have added compiler comments. A mess

Collapse
 
elsyng profile image
Ellis • Edited

What is "silly" is that json does not allow comments, when many/most other computing languages/notations do. If you don't want to insert comments, then don't. I personally think comments are equally appropriate in json as in javascript or java or any other language or notation. Equally good or equally bad or equally whatever. I know a number of languages which did not supports comments first, but they were added later, or they were expanded later (eg: /* vs // vs //* or whatever). That it is not there now is not a proof for that it should not be.

First there were no comments. Then came comments. Then we were told: comment as much as you can. And we would write code, and write separate long documents to document the code, then we had to keep them updated and we didn't, so no-one read those documents. Then came: comments are bad, write self-documenting code.........

Change is good.

Collapse
 
zirkelc profile image
Chris Cook

I don't quite understand what you're getting at. What does Java, Python or Webpack have to do with JSON comments? And why would they have handled it differently?

In my opinion, JSON became popular because a) JSON is less verbose than the alternative XML, which saved a lot of bandwidth back when the internet was slow, and b) JSON is a valid JavaScript object (or array) that you can insert into your code without modification.

And because you mentioned Java and Python: the last point b) doesn't apply to either. Java does not have a simple record type { }' like JS does. While Python does have dicts, its boolean values are different from JS (Truevstrue`). So in both cases, JSON cannot be inserted into the code of Java or Python in the same way it can in JS. That means a JSON parser is required for anyway. So what's the issue with comments then?

Collapse
 
benjamin_peikes profile image
Benjamin Peikes

If you need comments, but the tool doesnt support it, write a .jsonc file, and make your build convert it to .json before using it.

There is a good reason json does not supoort comments. Its data, so you would never be able to round trip from data to data structures, and then back to data.

Also, json does not guarentee ordering of keys (only arrays), so how can you be sure that the comments end up in the right place?

Collapse
 
c9hp profile image
C9 • Edited

You can use HJSON (Human JSON) you can use comments:
# and // and even /* */
and also some interesting features for easier use. Like no need to quote every word.

Collapse
 
zirkelc profile image
Chris Cook

The problem with custom JSON formats like JSON5, JSONC, HJSON, etc is that they are not well supported by the tools that use them. Do you use HJSON for any config?

Collapse
 
c9hp profile image
C9

No i just said this is an option for those who want this. I have never used HJson. I don't have much work with JSON but if i had, I would choose original JSON for the reason you mentioned.

Collapse
 
mjaggard profile image
mjaggard

Whilst package.json doesn't support comments as such, it does support a "//" notation for including comments in certain places.