loading...

How to add comments to package.json?

napolux profile image Francesco Napoletano ・1 min read

When you're bored, you usually have your best ideas. While wasting some time on twitter this morning I met a legit question coming from @caludio (you should really follow him):

Are there any plans to make it possible for package.json to contain comments? I can understand the implications but i.e., I would like to write the reason why I had to lock a package to a specific version (hello, TypeScript)

And I was a bit confused... It's a JSON, I can do whatever I want with it! So I've put together some code just to run an npm install on it...

{
  "name": "napolux-frontend",
  "version": "1.0.0",
  "description": "it's a test",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.3.1",
    "babel-polyfill": "^6.26.0",
    "gulp": "^4.0.0",
    "gulp-babel": "^8.0.0",
    "gulp-rename": "^1.4.0",
    "gulp-uglify": "^3.0.1"
  },
  "dependencies": {
    "jquery": "^3.3.1"
  },
  "comments": {
    "dependencies": "we use jQuery because of reasons",
    "repository": "our beloved repo",
    "license": "we love MIT, so why not",
    "devDependencies": {
      "@babel/core": "it's @ version 7.2.2 because of...",
      "gulp-rename": "why not"
    }
  }
}

It works! It's not the best possible solution, for sure no inline comments for example, but if you maintain the structure of your comments section very close to the one of package.json it will be definetely readable!

This post originally appeared on https://coding.napolux.com, but was brought to dev.to for your reading pleasure ❤.

Posted on by:

napolux profile

Francesco Napoletano

@napolux

Software Engineer, husband, programmer, videogames player, technical writer. Opinions expressed here are my own.

Discussion

pic
Editor guide
 

The convention I have started using is the following:

{
  "@comment dependencies": [
    "These are the comments for the `dependencies` section.",
    "The name of the section being commented is included in the key after the `@comment` 'annotation' to ensure the keys are unique.",
    "That is, using just \"@comment\" would not be sufficient if you need to add another comment at the same level.",
    "Because JSON doesn't allow a multiline string or understand a line continuation operator, just use an array for each line of the comment.",
    "Since this is embedded in JSON, the keys should be unique.",
    "Otherwise JSON validators, such as ones built into IDE's, will complain.",
    "Or some tools, such as running `npm install something --save`, will rewrite the `package.json` file but with duplicate keys removed.",
    "",
    "@package react - Using an `@package` 'annotation` could be how you add comments specific to particular packages."
  ],
  "dependencies": {
    ...
  },
  "scripts": {
    "@comment build": "This comment is about the build script.",
    "build": "...",

    "@comment start": [
      "This comment is about the `start` script.",
      "It is wrapped in an array to allow line formatting.",
      "",
      "@option {number} --port - The port the server should listen on."
    ],
    "start": "...",

    "@comment test": "This comment is about the test script.",
    "test": "..."
  }
}
Enter fullscreen mode Exit fullscreen mode

Note: For the dependencies, devDependencies, etc sections, the comment annotations can't be added directly above the individual package dependencies inside the configuration object since npm is expecting the key to be the name of an npm package. Hence the reason for the @comment dependencies.

Note: In certain contexts, such as in the scripts object, some editors/IDEs may complain about the array. In the scripts context, VS Code expects a string for the value -- not an array.

A top-level comment annotation can also be added similar to what Francesco presented.

{
  "@comment": {
    "dependencies": "we use jQuery because of reasons",
    "repository": "our beloved repo",
    "license": "we love MIT, so why not",
    "devDependencies": {
      "@babel/core": "it's @ version 7.2.2 because of...",
      "gulp-rename": "why not"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

However, I like keeping the comment as close as possible to what it applies to.

 

I have changed a few things in how I add comments to package.json. Here is an example of the new convention I am following:

{
  "@comment dependencies": [
    "These are the comments for the `dependencies` section.",
    "The name of the section being commented is included in the key after the `@comment` 'annotation' to ensure the keys are unique.",
    "That is, using just \"@comment\" would not be sufficient if you need to add another comment at the same level.",
    "Because JSON doesn't allow a multiline string or understand a line continuation operator, just use an array for each line of the comment.",
    "Since this is embedded in JSON, the keys should be unique.",
    "Otherwise JSON validators, such as ones built into IDE's, will complain.",
    "Or some tools, such as running `npm install something --save`, will rewrite the `package.json` file but with duplicate keys removed.",
    "The section below is an object with properties where each property matches the NPM package's name.",
    "The comment about the package is the value of the property. This property may be a single string or an array of strings.",
    {
      "react": "Comment about this package."
    }
  ],
  "dependencies": {
    ...
  },
  "@comment scripts": {
    "build: [
      "This comment is about the build script. It may be a string or any array of strings.",
      "In the old convention, the comment was within `scripts`, next to the script it applied to.",
      "In this new convention, it is in its own section.",
      "This was done so that the comments don't appear as a script to a tool that reads the `scripts` section."
    ],
    "start": [
      "This comment is about the `start` script.",
      "It is wrapped in an array to allow line formatting.",
      "",
      "@option {number} --port - The port the server should listen on."
    ],
  },
  "scripts": {
    "build": "...",
    "start": "...",
    "test": "..."
  }
}
Enter fullscreen mode Exit fullscreen mode
 

I really like this idea; it should be a standard. Let's discuss and vote up in npm / cli / issues / #677

 

I think you might wanna keep things like this in a separate place, like Github issues, or maybe just some file. But I don’t think package.json is a good place.

 

It’s the best place: right next (oh, well, as close as possible with a file format that was not made for writing configuration) to where you do the thing. You don’t want anybody (even your future self), to think “Oh, look, someone bumped babel/preset-env to 7.3 but forgot to do the same with babel/core”. And that’s what people are going to think, not “Oh, look, babel/preset-env is on 7.3, but babel/core is on 7.2, let’s walk through all the GitHub issues to see if it’s intentional or not.”

 

Why do you think package.json is not a good place for comments about things in package.json?

 

I just feel most people wouldn’t be looking for this kind of information in package.json. But if you wanna put stuff in there then sure go ahead.

 

Could be. But having them in the same file makes them super close to the packages and their definitions.

 

Agree, I think this is the preference of most people

 

Yeah I guess. Everyone has their own preferences.

 

This could be an interesting discussion which discussed the extending the package json file, such as using JSON5, YAML, HJSON instead of just plain JSON.

npm.community/t/support-package-js...

And most of these syntax standards support comments out of box. Love to see further result. Thank you for starting the discussion @napolux

 

Thanks for this - it's a solution to a problem I've had a couple of times while teaching, but it never occurred to me to try this!