How To Use JSON with Comments for Configs

// 21 comments

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.

/

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.

/

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" } }

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.