# The package.json guide

> Learn how the package.json file works in Node.js projects, from the name, version, scripts, and dependencies fields to semver version rules.

Author: Flavio Copes | Published: 2018-08-03 | Canonical: https://flaviocopes.com/package-json/

If you work with [JavaScript](https://flaviocopes.com/javascript/), or you've ever interacted with a JavaScript project, [Node.js](https://flaviocopes.com/nodejs/) or a frontend project, you surely met the `package.json` file.

What's that for? What should you know about it, and what are some of the cool things you can do with it?

The `package.json` file is kind of a manifest for your project. It can do a lot of things, completely unrelated. It's a central repository of configuration for tools, for example. It's also where [`npm`](https://flaviocopes.com/npm/) and [`yarn`](https://flaviocopes.com/yarn/) store the names and versions of the package it installed.

<!-- TOC -->

- [The file structure](#the-file-structure)
- [Properties breakdown](#properties-breakdown)
  - [name](#name)
  - [author](#author)
  - [contributors](#contributors)
  - [bugs](#bugs)
  - [homepage](#homepage)
  - [version](#version)
  - [license](#license)
  - [keywords](#keywords)
  - [description](#description)
  - [repository](#repository)
  - [main](#main)
  - [private](#private)
  - [scripts](#scripts)
  - [dependencies](#dependencies)
  - [devDependencies](#devdependencies)
  - [engines](#engines)
  - [browserslist](#browserslist)
  - [Command-specific properties](#command-specific-properties)
- [Package versions](#package-versions)

<!-- /TOC -->

## The file structure

Here's an example package.json file:

```json
{

}
```

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](https://flaviocopes.com/json/) format, otherwise it cannot be read by programs that try to access its properties programmatically.

If you're building a Node.js package that you want to distribute over `npm` things change radically, and you must have a set of properties that will help other people use it. We'll see more about this later on.

This is another package.json:

```json
{
  "name": "test-project"
}
```

It defines a `name` property, which tells the name of the app, or package, that's contained in the same folder where this file lives.

Here's a much more complex example, which I extracted this from a sample [Vue.js](https://flaviocopes.com/vue-introduction/) application:

```json
{
  "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"
  ]
}
```

there are _lots_ of things going on here:

- `name` sets the application/package name
- `version` indicates the current version
- `description` is a brief description of the app/package
- `main` set the entry point for the application
- `private` if set to `true` prevents the app/package to be accidentally published on `npm`
- `scripts` defines a set of node scripts you can run
- `dependencies` sets a list of `npm` packages installed as dependencies
- `devDependencies`  sets a list of `npm` packages installed as development dependencies
- `engines` sets which versions of Node this package/app works on
- `browserslist` is used to tell which browsers (and their versions) you want to support

All those properties are used by either `npm` or other tools that we can use.

## Properties breakdown

This section describes the properties you can use in detail. I refer to "package" but the same thing applies to local applications which you do not use as packages.

Most of those properties are only used on the <https://www.npmjs.com/>, other by scripts that interact with your code, like `npm` or others.

### name

Sets the package name.

Example:

```json
"name": "test-project"
```

The name must be less than 214 characters, must not have spaces, it can only contain lowercase letters, hyphens (`-`) or underscores (`_`).

This is because when a package is published on `npm`, it gets its own URL based on this property.

If you published this package publicly on [GitHub](https://flaviocopes.com/github/), a good value for this property is the GitHub repository name.

### author

Lists the package author name

Example:

```json
{
  "author": "Flavio Copes <your@email.com> (https://flaviocopes.com)"
}
```

Can also be used with this format:

```json
{
  "author": {
    "name": "Flavio Copes",
    "email": "your@email.com",
    "url": "https://flaviocopes.com"
  }
}
```

### contributors

As well as the author, the project can have one or more contributors. This property is an array that lists them.

Example:

```json
{
  "contributors": [
    "Flavio Copes <your@email.com> (https://flaviocopes.com)"
  ]
}
```

Can also be used with this format:

```json
{
  "contributors": [
    {
      "name": "Flavio Copes",
      "email": "your@email.com",
      "url": "https://flaviocopes.com"
    }
  ]
}
```

### bugs

Links to the package issue tracker, most likely a GitHub issues page

Example:

```json
{
  "bugs": "https://github.com/flaviocopes/package/issues"
}
```

### homepage

Sets the package homepage

Example:

```json
{
  "homepage": "https://flaviocopes.com/package"
}
```

### version

Indicates the current version of the package.

Example:

```json
"version": "1.0.0"
```

This property follows the semantic versioning (semver) notation for versions, which means the version is always expressed with 3 numbers: `x.x.x`.

The first number is the major version, the second the minor version and the third is the patch version.

There is a meaning in these numbers: a release that only fixes bugs is a patch release, a release that introduces backward-compatible changes is a minor release, a major release can have breaking changes.

### license

Indicates the license of the package.

Example:

```json
"license": "MIT"
```

### keywords

This property contains an array of keywords that associate with what your package does.

Example:

```json
"keywords": [
  "email",
  "machine learning",
  "ai"
]
```

This helps people find your package when navigating similar packages, or when browsing the <https://www.npmjs.com/> website.

### description

This property contains a brief description of the package

Example:

```json
"description": "A package to work with strings"
```

This is especially useful if you decide to publish your package to `npm` so that people can find out what the package is about.

### repository

This property specifies where this package repository is located.

Example:

```json
"repository": "github:flaviocopes/testing",
```

Notice the `github` prefix. There are other popular services baked in:


```json
"repository": "gitlab:flaviocopes/testing",
```

```json
"repository": "bitbucket:flaviocopes/testing",
```

You can explicitly set the version control system:

```json
"repository": {
  "type": "git",
  "url": "https://github.com/flaviocopes/testing.git"
}
```

You can use different version control systems:

```json
"repository": {
  "type": "svn",
  "url": "..."
}
```

### main

Sets the entry point for the package.

When you import this package in an application, that's where the application will search for the module exports.

Example:

```json
"main": "src/main.js"
```

### private

if set to `true` prevents the app/package to be accidentally published on `npm`

Example:

```json
"private": true
```

### scripts

Defines a set of node scripts you can run

Example:

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

These scripts are command line applications. You can run them by calling `npm run XXXX` or `yarn XXXX`, where `XXXX` is the command name. Example: `npm run dev`.

You can use any name you want for a command, and scripts can do literally anything you want.

### dependencies

Sets a list of `npm` packages installed as dependencies.

When you install a package using npm or yarn:

```bash
npm install <PACKAGENAME>
yarn add <PACKAGENAME>
```

that package is automatically inserted in this list.

Example:

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

### devDependencies

Sets a list of `npm` packages installed as development dependencies.

They differ from `dependencies` because they are meant to be installed only on a development machine, not needed to run the code in production.

When you install a package using npm or yarn:

```bash
npm install --dev <PACKAGENAME>
yarn add --dev <PACKAGENAME>
```

that package is automatically inserted in this list.

Example:

```json
"devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.22.1"
}
```

### engines

Sets which versions of Node.js and other commands this package/app work on

Example:

```json
"engines": {
  "node": ">= 6.0.0",
  "npm": ">= 3.0.0",
  "yarn": "^0.13.0"
}
```

### browserslist

Is used to tell which browsers (and their versions) you want to support. It's referenced by Babel, Autoprefixer, and other tools, to only add the polyfills and fallbacks needed to the browsers you target.

Example:

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

This configuration means you want to support the last 2 major versions of all browsers with at least 1% of usage (from the [CanIUse.com](https://caniuse.com) stats), except IE8 and lower.

([see more](https://www.npmjs.com/package/browserslist))

### Command-specific properties

The `package.json` file can also host command-specific configuration, for example for Babel, [ESLint](https://flaviocopes.com/eslint/), and more.

Each has a specific property, like `eslintConfig`, `babel` and others. Those are command-specific, and you can find how to use those in the respective command/project documentation.

## Package versions

You have seen in the description above version numbers like these: `~3.0.0` or `^0.13.0`. What do they mean, and which other version specifiers can you use?

That symbol specifies which updates you package accepts, from that dependency.

Given that using semver (semantic versioning) all versions have 3 digits, the first being the major release, the second the minor release and the third is the patch release, you have these rules:

- `~`: if you write `~0.13.0`, you want to only update patch releases: `0.13.1` is ok, but `0.14.0` is not.
- `^`: if you write `^0.13.0`, you want to update patch and minor releases: `0.13.1`, `0.14.0` and so on.
- `*`: if you write `*`, that means you accept all updates, including major version upgrades.
- `>`: you accept any version higher than the one you specify
- `>=`: you accept any version equal to or higher than the one you specify
- `<=`: you accept any version equal or lower to the one you specify
- `<`: you accept any version lower to the one you specify

There are other rules, too:

- no symbol: you accept only that specific version you specify
- `latest`: you want to use the latest version available

and you can combine most of the above in ranges, like this: `1.0.0 || >=1.1.0 <1.2.0`, to either use 1.0.0 or one release from 1.1.0 up, but lower than 1.2.0.
