Stop using NPM wrong –save-dev

You see it all the time. There you are trying to install an innocent NPM plugin when BHAM, it happens, a DevOps engineer dies…

Ok so maybe I’m exaggerating a tiny bit but ‘gets very cross‘ is certainly accurate. What I’m talking about is the ‘–save-dev’ flag when adding a new NPM package to a project. For some reason this has now become the de facto standard and it’s, (mostly), wrong.

NPM install Ruby sass

The popular gulp-ruby-sass using –save-dev

NPM Install Grunt Compass

grunt-contrib-compass also recomending –save-dev

So what’s the problem with –save-dev?

Well nothing in theory. Like almost all other package managers NPM can distinguish between packages that should be installed in a production environment and packages that should be installed in a development environment. The obvious reason for this is that you’re probably not going to need all your javascript testing frameworks etc in production. However, unless you’re still FTPing CSS files up to the production server (bad), the chances are you’re also going to want gulp-ruby-sass or whatever else is in your default grunt task on the production server as well.

“But I run `git pull && npm install` on my server and it works fine, what are you on about?” you ask bewildered. Well, firstly congratulations for not using FTP, however what you should be doing is ‘npm install –production’. By default npm installs all packages including the dev ones, however, if you pass the ‘–production’ flag it will only install the production packages.

You can see where the problems start to come in. We now run nearly all of our deployments with Capistrano which we have setup to pass the ‘–production’ flag in by default. If a developer has installed a package with ‘–save-dev’ that needs to be run on the server the entire deployment fails, (gracefully, of course) and some poor DevOps engineer, (sometimes me), has to spend hours trying to work out why the default grunt task isn’t completing only to realise that it’s because the NPM package it’s trying to use isn’t on the server.

So next time you’re adding an NPM package take a moment and decide if it’s going to be required in production or not. If it is, don’t use ‘–save-dev’.

tldr: Don’t use ‘–save-dev’ to add NPM packages unless you’re absolutely sure that they’re not required in a production enviroment

4 thoughts on “Stop using NPM wrong –save-dev

I feel like there’s a reason for this ambiguity though. For example, when using ember-cli, most of the dependencies are installed in `devDependencies`, including the ones necessary to run a “production” build of the app. However, most people, when deploying, will use a build server and something like `ember install && ember build –environment=production`, then copy the contents of the `dist` folder to their web server.

I guess what I’m saying is if you use the ‘run on a build server then copy to web server’ approach for single page apps, this doesn’t matter as much. I think that’s probably why you see a lot of people using `–save-dev` on projects that have to be built / run with the `–production` flag on a production server.

I haven’t actually used ember so can’t really compare the two to be honest. Even on a build server though you should be using ‘–production’ for NPM, for speed apart from anything else. But that aside, I’d argue that using a build server is comparatively rare compared to deployment managers. Either way, developers should be aware of what ‘–save-dev’ does and if it’s appropriate.

I’m going to have to flat out disagree with you. The reason you put stuff like a build system and their modules in devDependancies is because you shouldn’t be building in a production environment, only your development environments. The documentation for gulp-sass-ruby flat out says to use ‘–save-dev’ so I’d sooner bet that you’re wrong rather than the folks at gulp-sass-ruby. I think you need to reevaluate how you deploy to a production environment.

Thanks for the comments. I actually addressed your points on reddit in a reply to ma-int but will repost below as well.

Ok so there are two different issues here. Firstly, is deployment process. Sure, as you say, in an ideal world we’re all working on single app sites that sites, sit on a dedicated server cluster, is 100% tested and put through a build server first with front-enders, devops etc all playing their respective roles. However, I’d argue that 99% of cases this isn’t happening, partly because it just isn’t needed and partly because of time, money etc. So you end up with package managers on the production server being run as part of the deployment process, which is perfectly acceptable in the majority of cases below enterprise level.
Secondly, I’m not saying don’t use –save-dev, I’m just trying to draw attention to what it does and get developers to stop and consider if it’s required or not and how it’s going to interact with the deployment process.

Comments are closed.