<onWebFocus />

Knowledge is only real when shared.

dependencies vs. devDependencies

August 23, 2021

How to use dependencies and devDependencies meaningfully.

Everybody has their own opinion about when and what for devDependencies should be used. Here we'll explore what they actually do and how to best leverage this functionality.

npm

npm was the first tool to popularize devDependencies in JavaScript. The intent is to provide a way to add dependencies to the package that will also be installed when a user downloads the published package from npm.

{
    "name": "my-package",
    "dependencies": {
        "react": "1.0.0"
    },
    "devDependencies": {
        "jest": "1.0.0"
    }
}

Assuming the above package.json running npm install will install all dependencies, in this case including jest. Running npm install --production or setting process.env.NODE_ENV to production will not install any devDependencies.

More importantly npm install will never install any devDependencies of the packages listed that are being installed. This way you don't have to worry about publishing unnecessary build or test dependencies to users of the package.

Used in this way devDependencies are packages required to develop the package later published to npm but will be obsolete once the package is built for distribution. Examples of such packages include build tools, testing frameworks, linters and formatters.

Frontend / Backend Projects

Most Frontend web projects are set-up like npm packages but without the intent to publish them to the registry. Since devDependencies were naturally available people started using them for use cases made up on the go. It is popular to place build tools and testing frameworks in devDependencies similar to published npm packages. With the exception that the separation is purely semantic. The build bundles all dependencies and the package to be deployed won't require any of the listed dependencies or devDependencies.

On the backend side a similar separation standard formed over time. There the idea was to only place dependencies required to run the server in production in dependencies while the devDependencies get pruned after the build. Pruning means removing all installed devDependencies from the node_modules folder and this can be accomplished with the npm prune --production command. The idea behind this is to minimize the space the application requires when deployed and to improve security in case any of the devDependencies contain mailicious code.

Recommendation

When you set up a new web project that's not going to be published to the npm registry you can install all dependencies regularly and there is no need to use devDependencies.

As an optimization for application that include their own server all of the build dependencies can be moved to devDependencies and pruned before starting the server. This only makes sense for large applications where reduction in size translates to actual cost savings and the application is so popular that all possible security precautions should be taken.