1209

What is the difference between:

npm install [package_name]

and:

npm install [package_name] --save

and:

npm install [package_name] --save-dev

What does this mean? And what is really the effect of --save and -dev keywords?

S. Hesam
  • 5,266
  • 3
  • 37
  • 59
nfort
  • 12,234
  • 3
  • 13
  • 13
  • 5
    yeah I am confused about this - if you use continuous integration like Jenkins, does Jenkins know to use the devDependencies modules for running tests? I assume so but it's not super obvious. – Alexander Mills Aug 12 '15 at 19:32
  • 10
    perhaps edit the question to also say, what is the functional difference between dependencies and devDependencies? – Alexander Mills Aug 12 '15 at 19:33
  • 12
    Packages installed via the --save-dev option are not re-installed when the user executes `npm install --production`. That's the operational difference (see [https://docs.npmjs.com/cli/install](https://docs.npmjs.com/cli/install) for more info). – Andrew Jul 20 '17 at 14:03
  • 5
    also if you set environment variable `NODE_ENV` to production, then just `npm install` automatically excludes development packages. – Muhammad Umer Jan 01 '18 at 22:58
  • The real problem is that this is just an unclear distinction that could be improved on the node / npm side. There is no noticable difference between --save and --save-dev when developing. To take the `moment.js` example: when running webpack, the `moment` code is taken from `node_modules` and included in the project. In this sense there is no difference with `typescript` which is also needed when running webpack. – Kokodoko Mar 19 '18 at 09:03

18 Answers18

960

The difference between --save and --save-dev may not be immediately noticeable if you have tried them both on your own projects. So here are a few examples...

Let's say you were building an app that used the moment package to parse and display dates. Your app is a scheduler so it really needs this package to run, as in: cannot run without it. In this case you would use

npm install moment --save

This would create a new value in your package.json

"dependencies": {
   ...
   "moment": "^2.17.1"
}

When you are developing, it really helps to use tools such as test suites and may need jasmine-core and karma. In this case you would use

npm install jasmine-core --save-dev
npm install karma --save-dev

This would also create a new value in your package.json

"devDependencies": {
    ...
    "jasmine-core": "^2.5.2",
    "karma": "^1.4.1",
}

You do not need the test suite to run the app in its normal state, so it is a --save-dev type dependency, nothing more. You can see how if you do not understand what is really happening, it is a bit hard to imagine.

Taken directly from NPM docs docs#dependencies

Dependencies

Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string that has one or more space-separated descriptors. Dependencies can also be identified with a tarball or git URL.

Please do not put test harnesses or transpilers in your dependencies object. See devDependencies, below.

Even in the docs, it asks you to use --save-dev for modules such as test harnesses.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Michael Bruce
  • 10,567
  • 2
  • 23
  • 31
  • 62
    IMO, i think the 'save' keyword is a problem. Why don't they make -dev flag for develop and -deploy for deployment. It make sense than 'save' keyword. – Thinh Vu Mar 17 '17 at 07:44
  • 2
    Why doesn't the package just know (decide) if it's a release package or a dev package and --save be used for both. Seems odd to make the installing user decide this, when the package developer creates the intent. – CodeGrue Jun 04 '17 at 01:21
  • 9
    CodeGrue, if you use jQuery only for testing React components it would go in save-dev, but you may not actually use it to build your main project. Yes, this is possible. So why would the packager know what you are doing with it? – Michael Bruce Jun 05 '17 at 23:04
  • 4
    Much clearer. I'm an embedded guy learning Bootstra + Node.js workflow for the first time. It's not obvious what the difference is off the cuff. – Leroy105 Mar 02 '18 at 00:24
  • it's still not quite clear: if I use a bundler (webpack) and sources don't work by themselves, do I have to save bundler as save or save-dev? Examples I've seen suggest that usually save-dev is used, but it's not quite clear why – YakovL Jan 23 '19 at 12:56
  • 4
    @YakovL save-dev means the packages are not installed when somebody else installs your package as their dependency. Packages that are only used to run scripts such as start/build will not be needed in that case, so they're put in dev-dependencies. If you're working on a web app and not on a package for use by others, you probably shouldn't worry about it at all. – riv Jun 06 '19 at 08:27
  • Good answer. Apart from the technical part, we also need a "theory" one, a "why" for it. – dawn Feb 10 '21 at 02:21
  • This is exactly the answer for the remaining questions asked in this page! Focused, good example. Thank you. – nambk Apr 03 '21 at 07:57
  • the author doesn't know how to choose keywords properly.. welcome to open source – devXen Jan 05 '22 at 01:31
  • Neither this, nor any other answer here, mentions the difference between a regular `npm install` and a `npm install --save` – Adham Mar 06 '23 at 04:45
  • 1
    @adham there is no difference, --save is default. – Michael Bruce Mar 07 '23 at 06:32
818
  • --save-dev is used to save the package for development purpose. Example: unit tests, minification..
  • --save is used to save the package required for the application to run.
Tuong Le
  • 18,533
  • 11
  • 50
  • 44
  • 191
    How are they different? When would I use one vs the other? Can I still use it the package in production if it is under --save-dev? – Dave Voyles Nov 08 '16 at 15:30
  • 26
    The answer succinctly answers your first two questions. The answer to the last question, "Can I still use the package in production if it is under --save-dev," is "no." While it's certainly _possible_ to do this, it is not intended. – Technetium Jan 18 '17 at 18:33
  • 83
    Shorthand versions: `-D` is short for `--save-dev` and `-S` is short for `--save` – chrisco Mar 26 '17 at 14:07
  • keyword here is "package" if your developing a web app, either will suffice. – VFein Mar 31 '17 at 13:59
  • Perfect examples of this are: "npm install grunt --save-dev", & "npm install typescript --save-dev" – Jack Jun 18 '17 at 19:18
  • 2
    App tools (save) vs developer tools (save-dev) – bajocode Aug 01 '17 at 08:16
  • 247
    This answer is frustratingly vague. Even a small example would go a long way to helping make this clearer. – Choylton B. Higginbottom Oct 31 '17 at 17:45
  • 54
    Note that as of npm version 5.0.0, the `--save` option is no longer necessary. If you do `npm install my-package`, it will add "my-package" as a dependency in the package.json file. – Martin Carel Feb 23 '18 at 23:27
  • 10
    The problem with most highest rated answers to this question is that they fail to distinct server-side and frontend projects. In the latter case, you ship transpiled JS/CSS code, where all dependencies are "already included". You don't even need to upload `node_modules`. In such projects, you can safely `--save-dev` all your installed packages and be done with that. – pilat Feb 07 '19 at 17:30
  • 1
    React to new comers is already complicated, these answers mystify it further. Agreed with -pilat – Prashant May 02 '21 at 11:08
  • A very important distinction: `--save` will install all of your dependencies whenever someone installs your package in their project. If your dependencies are bundled in your output and only used in your build process, then use `--save-dev` (or `-D`). Otherwise you are contributing to the monster that is node_modules – Tom Pietrosanti Jun 22 '21 at 16:20
231

By default, NPM simply installs a package under node_modules. When you're trying to install dependencies for your app/module, you would need to first install them, and then add them to the dependencies section of your package.json.

--save-dev adds the third-party package to the package's development dependencies. It won't be installed when someone runs npm install directly to install your package. It's typically only installed if someone clones your source repository first and then runs npm install in it.

--save adds the third-party package to the package's dependencies. It will be installed together with the package whenever someone runs npm install package.

Dev dependencies are those dependencies that are only needed for developing the package. That can include test runners, compilers, packagers, etc. Both types of dependencies are stored in the package's package.json file. --save adds to dependencies, --save-dev adds to devDependencies

npm install documentation can be referred here.

--

Please note that --save is now the default option, since NPM 5. Therefore, it is not explicitly needed anymore. It is possible to run npm install without the --save to achieve the same result.

Grateful
  • 9,685
  • 10
  • 45
  • 77
Lakshmi Swetha G
  • 2,691
  • 1
  • 9
  • 13
  • 63
    I suspected this... you can use --save-dev and --save interchangeably if you are build a web app that won't become a package i.e. downloaded from npm, if you are developing a package to share with others, it is important to understand the difference. – VFein Mar 31 '17 at 13:58
  • 27
    Thank you finally someone that says its purpose when you use npm install –  Sep 10 '17 at 02:37
  • 10
    --save is now default with npm install with the release of npm 5 in 2017 – nCardot Jul 11 '19 at 19:56
  • wait, why complex sentences? In DevDependecy developer can install the packages, and it will be updated the devDevependency only. So when new developer clone the project codebase and run npm install => here only `dependency package name is going to install.` in node_modules.. not developer's package as in Dev-dependency. – Anupam Maurya Sep 24 '19 at 11:51
  • 1
    How is this not the top answer? Anyone with the ability to read can see that `--save-dev` is for development; the other answers are useless. This answer specifies how `--save` and `--save-dev` actually **behave differently**. – Aaron Beaudoin Jul 25 '22 at 21:38
152

Let me give you an example,

  • You are a developer of a very SERIOUS npm library which uses different testing libraries to test the package.
  • Users download your library and want to use it in their code. Do they need to download your testing libraries as well? Maybe you use jest for testing and they use mocha. Do you want them to install jest as well? Just To run your library?

No. right? That's why they are in devDependencies.

When someone does, npm i yourPackage only the libraries required to RUN your library will be installed. Other libraries you used to bundle your code with or testing and mocking will not be installed because you put them in devDependencies. Pretty neat right?

So, Why do the developers need to expose the devDependancies?

Let's say your package is an open-source package and 100s of people are sending pull requests to your package. Then how they will test the package? They will git clone your repo and when they would do an npm i the dependencies as well as devDependencies.
Because they are not using your package. They are developing the package further, thus, in order to test your package they need to pass the existing test cases as well write new. So, they need to use your devDependencies which contain all the testing/building/mocking libraries that YOU used.

Aritra Chakraborty
  • 12,123
  • 3
  • 26
  • 35
81

A perfect example of this is:

$ npm install typescript --save-dev

In this case, you'd want to have Typescript (a javascript-parseable coding language) available for development, but once the app is deployed, it is no longer necessary, as all of the code has been transpiled to javascript. As such, it would make no sense to include it in the published app. Indeed, it would only take up space and increase download times.

Jack
  • 2,229
  • 2
  • 23
  • 37
  • 4
    The same goes for: "$ npm install grunt --save-dev", as it is useful for development, but not for deployment. – Jack Jun 18 '17 at 19:15
  • 1
    A side note: Microsoft suggests installing @types/xxx packages as dependencies, not devDependencies https://github.com/Microsoft/types-publisher/issues/81 – Dave Nov 06 '17 at 11:44
  • 2
    What I find confusing is how does this even matter? Packages saved using `--save` are still only saved in the `node_modules` folder. The code isn't included in the deployed website. – Kokodoko Nov 08 '17 at 15:12
  • 7
    @Kokodoko When you use the `--save-dev` flag, the package is added to your `devDependencies` object. If/when someone installs **your** package, all the `dependencies` are downloaded but the `devDependencies` are not, since they aren't required at runtime. As the answer stated, this saves them time and space. Developers working on your package files itself can just run `npm install` inside the package directory to install the `devDependencies` as well. – Jasjit Singh Marwah Mar 18 '18 at 07:18
  • So if you download a repo from github and type `npm install`, the `devDependencies` are ignored? – Kokodoko Mar 19 '18 at 09:00
  • @JasjitSinghMarwah the best answer in this topic at all. The only one which explains practical difference not just that --save are in "dependencies": { } and --save-dev in "devDependencies": { } and that dev packages should by installed with --save-dev. So when my package is in the act not real npm package but website or app and I know that its source code will never be published in npm registry or will be never privately included by other packages it does not matter I use dependencies or devDependencies. – mikep Jul 18 '18 at 14:25
  • @Kokodoko The other way around: `devDependencies` is ONLY installed when you download a repo from github and type `npm install`. – PoolloverNathan May 05 '21 at 12:34
36

As suggested by @andreas-hultgren in this answer and according to the npm docs:

If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use.

However, for webapp development, Yeoman (a scaffolding tool that installs a peer-reviewed, pre-written package.json file amongst other things) places all packages in devDependencies and nothing in dependencies, so it appears that the use of --save-dev is a safe bet in webapp development, at least.

Community
  • 1
  • 1
wayfarer_boy
  • 1,489
  • 21
  • 22
  • 3
    Note that I've run into issues when using gulp and installing packages with `--save-dev` where the package would not install its required dependancies. Running `--save` installed those missing dependancies. – Nick M Mar 03 '15 at 03:52
  • 20
    I'd also like to note that I'm now using `--save` for all but test and documentation dependencies (as per the npm docs). I'm beginning the think the Yeoman example I mentioned above is _not_ a good example of best practice. – wayfarer_boy Mar 03 '15 at 09:17
  • I think so too, why would you ever need `--save-dev` is only becoming less clear with every answer here :) – Kokodoko Nov 08 '17 at 15:16
26

--save-dev saves semver spec into "devDependencies" array in your package descriptor file, --save saves it into "dependencies" instead.

alex
  • 11,935
  • 3
  • 30
  • 42
  • 92
    and what's the functional difference? – ahnbizcad Apr 04 '15 at 16:22
  • 9
    this answer makes the most sense to me, devDependencies are then required for development but not production, so htmllint, sass compilation etc and Dependencies are for production requirements, such as Diaporama that will need to be present for things to run. – miller the gorilla Jul 19 '16 at 09:37
  • 3
    @ahnbizcad It's answered better [here](http://stackoverflow.com/questions/18875674/whats-the-difference-between-dependencies-devdependencies-and-peerdependencies) but the primary functional difference is that devDependencies are not transitively included. – Pace Sep 08 '16 at 15:54
  • Isn't the most intuitive way to describe it for someone who doesn't already know, this?: Dev `--save-dev` makes packages local to your project, whereas `--save` makes them local to your installation of node? – ahnbizcad Sep 08 '16 at 17:34
21

--save-dev is used for modules used in development of the application,not require while running it in production environment --save is used to add it in package.json and it is required for running of the application.

Example: express,body-parser,lodash,helmet,mysql all these are used while running the application use --save to put in dependencies while mocha,istanbul,chai,sonarqube-scanner all are used during development ,so put those in dev-dependencies .

npm link or npm install will also install the dev-dependency modules along with dependency modules in your project folder

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Biswadev
  • 1,456
  • 11
  • 24
17

Read Complete And Forget --save-dev Headache

Simplest answer is that --save-dev is useful when you are creating packages for other developers and want to host your package at NPM Registry like lodash, mongoose, express etc. When you are building or writing a Node Server there is no difference between --save and --save-dev because your Node Server implementation is private to you and you will never publish it on NPM.

How NPM Install Works

Whenever we install a new package using npm like npm install express then NPM installs that package to our system and put it into node_modules folder, now NPM will analyze the package.json file of newly installed package i.e express in this case, after analyzing NPM will install all those packages which were mentioned in dependencies section of package.json file of express package. After installing those packages on which express was dependent NPM again analyze the package.json file of all newly installed packages and again install the packages for them, this cycle goes on until all packages are available into node_modules folder to function properly. You can check package dependencies by running npm list in terminal where terminal should point location of your project directory.

How --save-dev Is Related To Above Explained Stuff

Suppose you want to create a new package like express, now while development of this new package you probably want to write some unit testing code and test the package with any other available testing package let's assume mocha in this case. Now you know mocha is only required to test the package not required to use the package. In this case you should install mocha using --save-dev flag, otherwise NPM will install it whenever a developer install your package using NPM. So if we want a dependency not installed when someone install our package from NPM we must install that package using --save-dev in development phase.

Last Thing

Do not mix --save-dev with collaboration development, if someone cloned your package code from a source version control system like github then NPM will surely install all devDependencies i.e package installed using --save-dev also.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Pawan Bishnoi
  • 1,759
  • 8
  • 19
14

Clear answers are already provided. But it's worth mentioning how devDependencies affects installing packages:

By default, npm install will install all modules listed as dependencies in package.json . With the --production flag (or when the NODE_ENV environment variable is set to production ), npm will not install modules listed in devDependencies .

See: https://docs.npmjs.com/cli/install

Alireza
  • 10,237
  • 6
  • 43
  • 59
14

When you install an npm package using npm install <package-name>, you are installing it as a dependency.

The package is automatically listed in the package.json file, under the dependencies list (as of npm 5: before you had to manually specify --save).
ex. npm install lodash
After pressing enter check your package.json file.

"dependencies": {
    "lodash": "4.x",  
},

When you add the -D flag, or --save-dev, you are installing it as a development dependency, which adds it to the devDependencies list.

ex. npm install --save-dev lite-server
After pressing enter check your package.json file

"devDependencies": {
    "lite-server": "^2.6.1"
},

Development dependencies are intended as development-only packages, that are unneeded in production. For example testing packages, webpack, or Babel.

When you go in production, if you type npm install and the folder contains a package.json file, they are installed, as npm assumes this is a development deploy.

You need to set the --production flag (npm install --production) to avoid installing those development dependencies.

YakovL
  • 7,557
  • 12
  • 62
  • 102
vikky singh
  • 356
  • 3
  • 6
11

All explanations here are great, but lacking a very important thing: How do you install production dependencies only? (without the development dependencies). We separate dependencies from devDependencies by using --save or --save-dev. To install all we use:

npm i

To install only production packages we should use:

npm i --only=production
Ronny Sherer
  • 8,349
  • 1
  • 22
  • 9
10

You generally don't want to bloat production package with things that you only intend to use for Development purposes.

Use --save-dev (or -D) option to separate packages such as Unit Test frameworks (jest, jasmine, mocha, chai, etc.)

Any other packages that your app needs for Production, should be installed using --save (or -S).

npm install --save lodash       //prod dependency
npm install -S moment           // "       "
npm install -S opentracing      // "       "

npm install -D jest                 //dev only dependency
npm install --save-dev typescript   //dev only dependency

If you open the package.json file then you will see these entries listed under two different sections:

"dependencies": {
  "lodash": "4.x",
  "moment": "2.x",
  "opentracing": "^0.14.1"
},

"devDependencies": {
    "jest": "22.x",
    "typescript": "^2.8.3"
},
ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
velhala
  • 161
  • 1
  • 5
  • I find this one of the clearest (simple and short) answers, but I’m still wondering what the functional difference really is. When I type `npm install`, both dependencies AND devDependencies get installed, so there doesn’t seem to be any difference? – Kokodoko May 06 '21 at 10:39
9
  1. --save-dev (only used in the development, not in production)

  2. --save (production dependencies)

  3. --global or -g (used globally i.e can be used anywhere in our local system)

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Shubham
  • 91
  • 1
  • 1
1

People use npm on production to do wicked cool stuff, Node.js is an example of this, so you don't want all your dev tools being run.

If you are using gulp (or similar) to create build files to put on your server then it doesn't really matter.

Tristanisginger
  • 2,181
  • 4
  • 28
  • 41
0

I want to add some of my ideas as

I think all differences will appear when someone uses your codes instead of using by yourself

For example, you write an HTTP library called node's request

In your library,

you used lodash to handle string and object, without lodash, your codes cannot run

If someone uses your HTTP library as a part of his code. Your codes will be compiled with his.

your codes need lodash, So you need to put in dependencies to compile


If you write a project like monaco-editor, which is a web editor,

you have bundled all your codes and your product env library using webpack, when build completed, only have a monaco-min.js

So someone doesn't care whether --save or --save-dependencies, only he needs is monaco-min.js

Summary:

  1. If someone wants to compile your codes (use as a library), put lodash which used by your codes into dependencies

  2. If someone want to add more feature to your codes, he needs unit test and compiler, put these into dev-dependencies

nuclear
  • 3,181
  • 3
  • 19
  • 38
0

Basically We Write

npm install package_name

But specially for Testing Purpose we don't need to run some package while Application is Running in Normal State so that Node introduce good way to solve this problem. Whenever we write

npm install package_name --save-dev

at that time this package is only installed for development purpose.

yash sanghavi
  • 368
  • 3
  • 5
-1

as --save is default option for npm, so I use

npm i package 

and for --save-dev, I use

npm i package -D

default option will install package as project dependency where as -D is for development dependencies like testing, lint etc. and install package for development process

you can find all the flags here https://docs.npmjs.com/cli/v8/commands/npm-install

tomcat
  • 1,798
  • 2
  • 11
  • 14
  • 6
    this doesn't explain what's the difference between them. This shouldn't be posted as an answer, but rather as a comment – YakovL Jan 04 '22 at 18:43