The package.json guide

Manvi Chaddha
Last Updated: May 13, 2022

Introduction

If you use JavaScript in your projects or have interacted with JavaScript projects, Node.js, or front-end projects, you will definitely encounter a package.json file.

The package.json is a central repository for tool configuration. The file exists at the root of the JavaScript project and is used for managing the project dependencies, scripts, versions, and a lot more. As a developer in the Node.js ecosystem, understanding the basics of package.json is one of the first steps to kicking off your development experience with Node.js.

This blog will discuss the Package.json file in detail.

Understanding the File structure

The simplest Package.json file will look like this.

{

}

It's empty! There are no fixed requirements of what should be in a package.json file for an application. The only requirement is that it respects the JSON format; otherwise, it cannot be read by programs that try to access its properties programmatically.

However, if you are building a node.js application that you wish to distribute over npm, the package.json file must java a set of properties that will help other people use it.

Let's take a look at another package.json file which was extracted from a sample vue.js application.

{

    "name": "test-project",

    "version": "1.0.0",

    "description": "A Vue.js project",

    "main": "src/main.js",

    "private": true,

    "scripts": {

      "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",

      "start": "npm run dev",

      "unit": "jest --config test/unit/jest.conf.js --coverage",

      "test": "npm run unit",

      "lint": "eslint --ext .js,.vue src test/unit",

      "build": "node build/build.js"

    },

    "dependencies": {

      "vue": "^2.5.2"

    },

    "devDependencies": {

      "autoprefixer": "^7.1.2",

      "babel-core": "^6.22.1",

      "babel-eslint": "^8.2.1",

      "babel-helper-vue-jsx-merge-props": "^2.0.3",

      "babel-jest": "^21.0.2",

      "babel-loader": "^7.1.1",

      "babel-plugin-dynamic-import-node": "^1.2.0",

      "babel-plugin-syntax-jsx": "^6.18.0",

      "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",

      "babel-plugin-transform-runtime": "^6.22.0",

      "babel-plugin-transform-vue-jsx": "^3.5.0",

      "babel-preset-env": "^1.3.2",

      "babel-preset-stage-2": "^6.22.0",

      "chalk": "^2.0.1",

      "copy-webpack-plugin": "^4.0.1",

      "css-loader": "^0.28.0",

      "eslint": "^4.15.0",

      "eslint-config-airbnb-base": "^11.3.0",

      "eslint-friendly-formatter": "^3.0.0",

      "eslint-import-resolver-webpack": "^0.8.3",

      "eslint-loader": "^1.7.1",

      "eslint-plugin-import": "^2.7.0",

      "eslint-plugin-vue": "^4.0.0",

      "extract-text-webpack-plugin": "^3.0.0",

      "file-loader": "^1.1.4",

      "friendly-errors-webpack-plugin": "^1.6.1",

      "html-webpack-plugin": "^2.30.1",

      "jest": "^22.0.4",

      "jest-serializer-vue": "^0.3.0",

      "node-notifier": "^5.1.2",

      "optimize-css-assets-webpack-plugin": "^3.2.0",

      "ora": "^1.2.0",

      "portfinder": "^1.0.13",

      "postcss-import": "^11.0.0",

      "postcss-loader": "^2.0.8",

      "postcss-url": "^7.2.1",

      "rimraf": "^2.6.0",

      "semver": "^5.3.0",

      "shelljs": "^0.7.6",

      "uglifyjs-webpack-plugin": "^1.1.1",

      "url-loader": "^0.5.8",

      "vue-jest": "^1.0.2",

      "vue-loader": "^13.3.0",

      "vue-style-loader": "^3.0.1",

      "vue-template-compiler": "^2.5.2",

      "webpack": "^3.6.0",

      "webpack-bundle-analyzer": "^2.9.0",

      "webpack-dev-server": "^2.9.1",

      "webpack-merge": "^4.1.0"

    },

    "engines": {

      "node": ">= 6.0.0",

      "npm": ">= 3.0.0"

    },

    "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"]

  }

 


Anxious after seeing the package.json file?

Don't feel stressed; we will closely examine the properties of the package.json file in this blog.

If you observe carefully, you will notice that basically, the package.json file contains ten properties. These ten properties are listed below, along with their usage.

PropertyUsage
versionIndicates the current version
nameUsed to set the application/package name.
descriptionThis includes a brief description of the app/package.
mainIt sets the entry property of the application.
privateIf this is set to true, it will prevent the app/package from being accidentally published on npm.
scriptsDefines a set of node scripts that you can run.
dependenciesIt is used to enlist a set of npm packages installed as dependencies.
devDependencies

It is used to enlist a set of npm packages installed as development

dependencies

enginesThis is used to set the version of node.js on which the app works on
browserslistIt is used to tell which browsers with their versions the app/package supports.

 

Things might seem a bit less complex now !!



You must go through the package.json file once more and see if it makes sense to you now. It is essential to note that these properties are used by either npm or other tools that we can use.

Properties Breakdown

Let's examine the attributes that can be used in detail now:

1. name

Used to set the package name, the name must be less than 214 characters, not have spaces, and contain only lowercase letters, hyphens, or underscores.

Example;

"name": "test-project",

The name being so restrictive is when a package is published on npm; a URL is assigned to it on this property. 

2.  author

It is used to list the author names of the package.

{
  "author": "Joe <joe@whatever.com> (https://whatever.com)"
}

 It can be simplified by destructuring in the following format.

{
    "author": {
      "name": "Joe",
      "email": "joe@whatever.com",
      "url": "https://whatever.com"
    }
}

 

 3. contributors

A project can have more than one contributor. An array of lists is used to specify the contributors list.

Consider the following example.

{
    "contributors": ["Joe <joe@whatever.com> (https://whatever.com)"]
}

 This again can be destructured in the following format:

{
    "contributors": [
      {
        "name": "Joe",
        "email": "joe@whatever.com",
        "url": "https://whatever.com"
      }
    ]
  }

 

4. bugs

This is typically used to link to the package issue tracker, most likely a GitHub issue page. 

{
    "bugs": "https://github.com/whatever/package/issues"
}

 

5. homepage

It is used to set the homepage of the package. An example is:


{  
 "homepage": "https://whatever.com/package"
}

 

6. version

This indicates the current version of the package. Note that the package version follows the semver notation for versions; the version number is always expressed in the following format, x.x.x.

The first x is used to denote the major version; the second is used to denote the minor version and the third one for the patch version.

A change in patch represents a bugfix that does not break anything; a change in a minor version represents a new functionality that does not break anything. A change in a major version represents a large change that breaks the compatibility. 

An example is:

"version": "1.0.0"

It is important to note that In package.json, you can set which versions you want to upgrade to (patch or minor), using the semver notation, for example:

  • if you write ~0.13.0, you want only to update patch releases: 0.13.1 is ok, but 0.14.0 is not.
  • If you write ^0.13.0, you want to get updates that do not change the leftmost non-zero number: 0.13.1, 0.13.2, and so on. If you write ^1.13.0, you will get the patch and minor releases: 1.13.1, 1.14.0, and so on up to 2.0.0 but not 2.0.0.
  • if you write 0.13.0, that is the exact version that will be used, always


7. repository

This property specifies the place where the package repository is located.

The prefix github specifies that the repository is located in Github.

"repository": "github:whatever/testing",

If the repository is located in bitbucket, 

"repository": "bitbucket:whatever/testing",

What if the repository is located in gitlab?

The answer is simply to replace the prefix with gitlab.

The above declaration can be destructured in the following format:

"repository": {
    "type": "git",
    "url": "https://github.com/whatever/testing.git"
  }

 

8. scripts:

This property takes an object with as many key/value pairs as desired; each of the key is the name of the command that can be run, the corresponding value is the actual command that is run.

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "unit": "jest --config test/unit/jest.conf.js --coverage",
    "test": "npm run unit",
    "lint": "eslint --ext .js,.vue src test/unit",
    "build": "node build/build.js"
  }
 


You can run these commands by calling npm run xxxx or yarn xxxx, where xxxx is the command name.

For example, npm run unit.

9. dependencies

The dependencies property is where the dependencies that the module uses are defined. Note that the package is automatically inserted in this list whenever a package is installed using npm or yarn.

"dependencies": {
  "vue": "^2.5.2"
}

10. devDependencies

The property is almost identical to the dependencies property, with a key difference specifies the dependencies that the module needs to run in development.

"devDependencies": {
  "escape-html": "^1.0.3",
  "lucene-query-parser": "^1.0.1"
}

 

Some other useful properties are:

  • main -> It sets the entry point for the package; whenever a package is imported in an application, that's where the application searches for the module exports.
  • engines -> This is used to set which version of Node.js and other commands that the application/package works on.
  • browserslist -> It is used to tell which browsers the application supports.

Yet another important file, called the package-lock.json, is automatically created when the node package manager you are using in your application is v5.x.x.

At first sight, the dependencies look quite similar to the package.json file, but it's more verbose.

The Package-lock.json file

As per the official documentation, The goal of the package-lock.json file is to keep track of the exact version of every package that is installed so that a product is 100% reproducible in the same way even if packages are updated their maintainers.

To understand the need of a package-lock.json file, it is crucial to understand a scenario. Consider that you are implementing a project in express, at the time of the creation of the project, the latest version of express was 4.15.4, so inside the package.json file, "express": "^4.15.4" will be added as the dependency.

(^4.15.4 signifies that at a minimum version 4.15.4 should be used, but any higher version is also fine to use)

Now let's consider that maintainers of express released a bug fix; the latest version now is 4.15.5. 

Now another person who was contributing to your project along with you had a new feature to add. The person cloned the repository, and as you might have figured out, he would run "npm install".

Version 4.15.5 is a higher version with the same major version that is installed for both of them.

Now the situation is, You in your system has 4.15.4 version of express and the other person has 4.15.5. There might not be major differences but what if the bug fix affected the functionality that we are using our application will then produce different results with the two versions.

If it does not make sense to you in one go, it is recommended that you read out the version dependence of the package.json file once again. The concept is clearly explained there.

The goal of the package-lock.json file is to avoid the confusions likely to occur in the situation described above, where installing modules from the same package.json files results in two different installs. The package-lock.json sets your currently installed version of each package in stone, and npm will use those exact versions when running npm ci. The package-lock.json file needs to be committed to your Git repository, so it can be fetched by other people, if the project is public or you have collaborators, or if you use Git as a source for deployments.

What better way to understand than an example, run npm install cowsay in an empty folder.

The package-lock.json will look like this

{
    "requires": true,
    "lockfileVersion": 1,
    "dependencies": {
      "ansi-regex": {
        "version": "3.0.0",
        "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.
  0.0.tgz",
        "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
      },
      "cowsay": {
        "version": "1.3.1",
        "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz"
  ,
        "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkM
  Ajufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==",
        "requires": {
          "get-stdin": "^5.0.1",
          "optimist": "~0.6.1",
          "string-width": "~2.1.1",
          "strip-eof": "^1.0.0"
        }
      },
      "get-stdin": {
        "version": "5.0.1",
        "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.
  1.tgz",
        "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="
      },
      "is-fullwidth-code-point": {
        "version": "2.0.0",
        "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/
  is-fullwidth-code-point-2.0.0.tgz",
        "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
      },
      "minimist": {
        "version": "0.0.10",
        "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10
  .tgz",
        "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
      },
      "optimist": {
        "version": "0.6.1",
        "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
        "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
 
        "requires": {
          "minimist": "~0.0.1",
          "wordwrap": "~0.0.2"
        }
      },
      "string-width": {
        "version": "2.1.1",
        "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
        "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
        "requires": {
          "is-fullwidth-code-point": "^2.0.0",
          "strip-ansi": "^4.0.0"
        }
      },
      "strip-ansi": {
        "version": "4.0.0",
        "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
        "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
        "requires": {
          "ansi-regex": "^3.0.0"
        }
      },
      "strip-eof": {
        "version": "1.0.0",
        "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
        "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
      },
      "wordwrap": {
        "version": "0.0.3",
        "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
        "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
      }
    }
  }
 


It can be easily observed that cowsay depends on get-stdin, optimist, string-width and strip-eof, these packages in turn depends on other packages as can be seen from the requires property that some have, ansi-regex, is-fullwidth-code-point, minimist, wordwrap, strip-eof.

These dependencies are added in alphabetical order into the file. Each has a version field, a resolved field that points to the package location and integrity string that can be used to verify the package.

Frequently Asked Questions

  1. What is Package.json?
    The package.json is actually a central repository for tool configuration. The file exists at the root of the JavaScript project and is used for managing the project dependencies, scripts, versions and a lot more.
     
  2. What do you mean by semver notation for version number?
    The package version follows the semver notation for versions, the version number is always expressed in the following format, x.x.x.
    The first x is used to denote the major version, the second is used to denote the minor version and third one for the patch version.

Key Takeaways

The blog discussed the package.json file in detail. With this done you may now switch to explore web technologies from our blogs.

A common problem faced by all of us is that we prepare well, but during online assessments, we cannot solve the questions on time. To overcome this, Coding Ninjas have come up with an online mock test series. The mock tests for leading companies like Amazon, Microsoft, Google, Adobe, Flipkart, TCS, Wipro, and Accenture are free. Our team of experts has curated and designed these online mock test series to help you prepare better for your coding interview rounds. In this online test series, you will get multiple tests that include the latest coding interview questions. . Start preparing for the 2021 Amazon, Microsoft, etc., tech interviews now.

Was this article helpful ?
0 upvotes

Comments

No comments yet

Be the first to share what you think