The npm dedupe command is a helpful tool for optimizing your Node.js projects by reducing the size of the node_modules directory. It works by removing duplicate packages across dependencies by keeping the most suitable versions of each package to minimize duplication.
Here is the comprehensive guide to understanding the command and how to use it with the various configuration options:
Syntax
npm dedupe [options]
The npm dedupe attempts to reduce duplication of the dependencies in your node_modules directory. When the multiple versions of dependency are installed in the different places this command moves them up in hierarchy to avoid redundancies. It does not install the new dependencies but rearranges existing ones for efficiency. This is especially useful in the large projects where multiple versions of same packages are being used.
Configuration
global-style
In npm dedupe, the global-style option determines how the packages are installed when using the deduplication process. When set to true, it installs dependencies in the flat, global-style structure, similar to what is used for global installs rather than nesting them within each project node_modules directory. This can reduce duplication by sharing packages between projects. However, it may also lead to potential version conflicts since all packages are installed globally.
- Usage: --global-style
- Example: npm dedupe --global-style
legacy-bundling
The legacy-bundling option forces npm to install the dependencies in deeply nested structure, where each dependency's dependencies are installed in their own node_modules folder. This mimics how the older versions of npm (pre-v3) handled installations. While this can avoid certain version conflicts by keeping packages isolated, it results in the much larger node_modules folder and longer install times compared to flat structure used by default in modern npm.
- Usage: --legacy-bundling
- Example: npm dedupe --legacy-bundling
strict-peer-deps
The strict-peer-deps option ensures that npm strictly enforces peer dependency requirements. When it is set to true, it prevents npm from automatically installing or updating the dependencies if peer dependencies are not satisfied or if there are some version mismatches. Instead, it throws an error for ensuring that only compatible versions of packages are installed. This helps to avoid potential runtime issues due to incompatible peer dependencies but may require manual intervention to resolve the conflicts.
- Usage: --strict-peer-deps
- Example: npm dedupe --strict-peer-deps
package-lock
The package-lock option controls whether the npm updates package-lock.json file after deduplication. When set to true, the npm will update package-lock.json file to reflect new, deduplicated structure of the installed dependencies. This ensures that lock file stays in sync with actual state of node_modules by maintaining integrity of the dependency tree. If set to false, npm performs deduplication without updating lock file which could lead to inconsistencies between lock file and the installed packages.
- Usage: --package-lock=false
- Example: npm dedupe --package-lock=false
omit
The omit option allows you to exclude certain types of dependencies from being installed or considered during deduplication process. You can specify the dependency types such as 'dev', 'optional' or 'peer' to be omitted. For example, setting 'omit': ['dev'] will exclude the development dependencies from deduplication process for ensuring that only production dependencies are optimized. This is useful when you are preparing for the production deployment and do not want unnecessary dependencies installed..
- Usage: --omit=<type>
- Example: npm dedupe --omit=dev
ignore-scripts
ignore-scripts option disables execution of the lifecycle scripts (such as preinstall, postinstall, etc.) during deduplication process. When set to true, npm skips running these scripts which can help speed up deduplication and prevent the unwanted side effects from custom install scripts defined by packages. This is useful in environments where you want to ensure no arbitrary code is executed during dependency management. However skipping scripts may cause issues if scripts are necessary.
- Usage: --ignore-scripts
- Example: npm dedupe --ignore-scripts
audit
audit option controls whether npm performs the security audit during deduplication process. When set to true, npm runs security audit on deduplicated dependency tree, checking for known vulnerabilities in installed packages. If vulnerabilities are found, it reports them by allowing you to take action to fix the potential security issues. If set to false, the npm skips security audit which can make deduplication process faster but may leave vulnerabilities undetected.
- Usage: --audit=false
- Example: npm dedupe --audit=false
bin-links
bin-links option controls whether npm creates symlinks for package executables in node_modules/.bin directory. When set to true, the npm generates symlinks for executables provided by installed packages, allowing them to be easily run from command line. If set to false, the npm skips creating these symlinks which may reduce disk space usage but prevent access to the package executables via .bin folder. This option is useful in the environments where you do not need direct access to package binaries such as certain production builds.
- Usage: --bin-links=false
- Example: npm dedupe --bin-links=false
fund
The fund option controls whether npm displays funding information for deduplicated packages. When set to true, npm will show information about how to support the maintainers of installed packages often including links to their funding sources like OpenCollective or GitHub Sponsors. This helps the developers discover ways to contribute financially to projects they depend on. If set to false, npm will skip displaying this information during deduplication process which can streamline output in CI or production environments.
- Usage: --fund=false
- Example: npm dedupe --fund=false
dry-run
The dry-run option allows you to simulate deduplication process without actually making any changes. When set to true, the npm will output actions it would take such as removing duplicate dependencies and reorganizing node_modules folder without modifying any files or installing/removing packages. This is useful for previewing impact of deduplication and ensuring that it will not cause unintended side effects before applying changes. If set to false, npm proceeds with the actual deduplication.
- Usage: --dry-run
- Example: npm dedupe --dry-run
workspace
When this option is set, it limits deduplication process to only specified workspace. This allows you to focus the deduplication on particular package within workspace rather than applying it across all packages.
- Usage: --workspace=<workspace-name>
- Example: npm dedupe --workspace=frontend
workspaces
This option, when set to true then tells npm to deduplicate dependencies across all workspaces defined in project. This promotes more efficient dependency tree by ensuring that shared dependencies are installed at top level by minimizing duplication across different packages in monorepo.
- Usage: --workspaces
- Example: npm dedupe --workspaces
Note: In npm dedupe, workspace and workspaces options are used to specify handling of packages in monorepo setup where multiple packages are managed within the single repository.
include-workspace-root
Determines whether root workspace (the top-level project) is included in deduplication process. When set to true, npm will deduplicate dependencies not only in individual workspaces but also in the root project.
This ensures that shared dependencies between root and workspace packages are deduplicated by optimizing the overall structure. If set to false, deduplication process will only apply to individual workspaces by ignoring root project dependencies. This option is useful when managing dependencies across the monorepo with both root and workspace-level dependencies.
- Usage: --include-workspace-root
- Example: npm dedupe --include-workspace-root
install-links
Controls whether symlinks are created for local workspace packages. When set to true, npm will create symlinks between the workspace packages instead of duplicating their installations in each workspace node_modules folder. This allows the different packages in same workspace to share dependencies more efficiently by reducing redundancy. If set to false, npm will install each workspace package independently without symlinking, which may lead to larger node_modules directories but more isolated package environments.
- Usage: --install-links=false
- Example: npm dedupe --install-links=false
Example: To see the npm dedupe in action, let us start with the sample package.json file that has duplicate dependencies:
// package.json:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"lodash": "^4.17.21",
"express": "^4.17.1",
"body-parser": "^1.19.0"
},
"devDependencies": {
"lodash": "^4.17.15"
}
}
This file specifies the two versions of lodash. Running the npm dedupe will remove duplicate versions:
npm dedupe --dry-run
By running npm dedupe --dry-run on example package.json would simulate deduplication process and show the actions npm would take without actually making any changes. Here's what would likely happen:
- Identifying duplicate: npm will notice that lodash is listed in the both dependencies and devDependencies with different versions (^4.17.21 in dependencies and ^4.17.15 in devDependencies).
- Resolving the duplicate: Since version specified in dependencies (^4.17.21) is higher than the one in devDependencies (^4.17.15), the npm will deduplicate by keeping lodash@^4.17.21 and removing lower version from devDependencies.
Output:
Note: Above output indicates that lodash@^4.17.15 would be removed by leaving only lodash@^4.17.21 in node_modules.
Conclusion
Using the npm dedupe can significantly streamline your project dependency tree which will help to reduce the disk space usage and potentially speed up the load times. Whether you are maintaining the large monorepo or just want to keep the single project clean, it is a valuable command to keep in your toolkit.