Node Package Manager (NPM)
Node Package Manager (NPM) Interview with follow-up questions
1. What is Node Package Manager (NPM) and why is it important in Node.js?
npm (Node Package Manager) is the default package manager bundled with Node. It does three things: provides a CLI to install/update/remove packages, defines a project via package.json (metadata, dependencies, scripts), and connects to the npm registry — the world's largest software registry — to fetch published packages.
Why it's important: it lets you reuse a massive ecosystem instead of reinventing wheels, manages dependency trees and versions for you, locks exact versions in package-lock.json for reproducible installs, and standardizes tasks through scripts (npm run build, npm test).
npm install express # add a dependency
npm ci # clean, reproducible install from the lockfile
npm run dev # run a package.json script
Current points that signal up-to-date knowledge: use npm ci in CI/production for deterministic installs; run npm audit to surface known vulnerabilities and be mindful of supply-chain risk; npm workspaces support monorepos; and alternatives like pnpm (fast, disk-efficient via a content-addressed store) and Yarn are popular. Modern Node ships npm 11, and Node's Corepack can manage pnpm/Yarn versions.
Follow-up 1
What is the difference between local and global installation of packages?
The main difference between local and global installation of packages is the scope of their availability. When a package is installed locally, it is only available within the project directory where it was installed. This means that other projects on your machine will not have access to that package. On the other hand, when a package is installed globally, it is available for use in any project on your machine. Global packages are typically used for command-line tools or utilities that you want to be available system-wide.
Follow-up 2
How can you update a package using NPM?
To update a package using NPM, you can use the npm update command followed by the name of the package you want to update. For example, to update the express package, you would run npm update express. NPM will check for the latest version of the package and install it if it is different from the currently installed version. You can also use the npm outdated command to see a list of packages that have newer versions available.
Follow-up 3
Can you explain how to install packages using NPM?
To install packages using NPM, you can use the npm install command followed by the name of the package you want to install. For example, to install the express package, you would run npm install express. By default, NPM installs packages locally in the node_modules directory of your project. You can also specify the --global flag to install packages globally, which makes them available for use in any project on your machine.
Follow-up 4
What is package.json and what is its significance in a Node.js project?
package.json is a metadata file in a Node.js project that contains information about the project and its dependencies. It includes details such as the project name, version, description, author, and license. The package.json file is significant in a Node.js project because it serves as a central configuration file that defines the project's dependencies, scripts, and other metadata. It allows developers to easily manage and share their project's dependencies with others, making it easier to collaborate and reproduce the project in different environments.
2. How can you uninstall a package using NPM?
Use npm uninstall (aliases: npm remove, npm rm, npm un). It removes the package from node_modules and updates package.json and package-lock.json:
npm uninstall express
npm uninstall --save-dev eslint # or -D, removes from devDependencies
npm uninstall -g typescript # remove a globally installed package
Details worth mentioning: in current npm, the dependency-file update is automatic (the old --save flag is the default now), and you target dev or global installs with -D/--save-dev or -g. After uninstalling you can run npm install/npm ci to ensure the tree and lockfile are consistent. If you only want to drop it from the manifest without touching the install, --no-save does that.
Follow-up 1
What happens to the dependencies of a package when it is uninstalled?
When a package is uninstalled using NPM, its dependencies are not automatically uninstalled. NPM keeps track of the dependencies of each package separately. If a dependency is not required by any other installed package, it may be removed automatically. However, if other packages depend on the same dependency, it will not be removed.
Follow-up 2
How can you check the version of an installed package?
To check the version of an installed package using NPM, you can use the npm list command followed by the package name. For example, to check the version of a package named example-package, you can run the following command:
npm list example-package
Follow-up 3
What is the significance of the --save flag while installing a package?
The --save flag is used to save the installed package as a dependency in the package.json file of your project. This file keeps track of all the dependencies required by your project. When you use the --save flag, NPM will automatically add the package to the dependencies section of the package.json file. This is useful when you want to share your project with others or deploy it to a production environment, as it allows others to easily install all the required dependencies by running npm install.
3. What is the difference between dependencies and devDependencies in the package.json file?
Both list packages your project needs, but for different phases:
dependencies— required at runtime/production (e.g.express,pg). Installed by default and shipped with the app.devDependencies— needed only during development/build/test (e.g.eslint,jest/vitest,typescript, bundlers). Not needed to run the built app in production.
npm install express # -> dependencies
npm install -D typescript # -> devDependencies
The practical points: npm install installs both by default, but npm install --omit=dev (or NODE_ENV=production) installs only runtime deps — which is how you keep production images small. Putting a runtime requirement in devDependencies is a classic bug that works locally but breaks in production. Worth naming the siblings too: peerDependencies (a host package the consumer must provide, e.g. a React plugin) and optionalDependencies (install failures are tolerated).
Follow-up 1
When should a package be listed in dependencies?
A package should be listed in dependencies when it is required for the project to run in production. This includes packages that are necessary for the project's functionality and are used by the application code at runtime. Examples of packages that should be listed in dependencies are frameworks, libraries, and utilities that are essential for the project's operation.
Follow-up 2
When should a package be listed in devDependencies?
A package should be listed in devDependencies when it is only required during development. This includes packages that are used for tasks such as testing, linting, building, and other development-related tasks. These packages are not necessary for the project to run in production and are not used by the application code at runtime. Examples of packages that should be listed in devDependencies are testing frameworks, build tools, and code quality tools.
Follow-up 3
What happens if a package is listed in both dependencies and devDependencies?
If a package is listed in both dependencies and devDependencies, it means that the package is required for both production and development. In this case, when the project is deployed or published, the package will be installed as part of the dependencies. However, during development, the package will also be available in the devDependencies and can be used for development-related tasks. It is important to note that the version specified in dependencies will take precedence over the version specified in devDependencies if there is a conflict.
4. What is semantic versioning in NPM?
Semantic Versioning (SemVer) is the MAJOR.MINOR.PATCH scheme npm uses to communicate the nature of changes:
- MAJOR — breaking, incompatible API changes.
- MINOR — new features, backward-compatible.
- PATCH — backward-compatible bug fixes.
npm pairs this with range operators in package.json that control which updates you accept:
^1.2.3(caret) — allow MINOR + PATCH (>=1.2.3 <2.0.0); the default on install.~1.2.3(tilde) — allow PATCH only (>=1.2.3 <1.3.0).1.2.3— exact pin.
The point interviewers want: SemVer ranges let you get fixes automatically in theory, but the package-lock.json is what guarantees everyone installs the exact same resolved versions (and npm ci enforces it). The gotcha is that SemVer relies on publishers' discipline — a "patch" can still break you — so lockfiles + testing matter, and pre-1.0 (0.x) versions treat MINOR as potentially breaking. Pre-release tags like 1.0.0-beta.1 are also part of the spec.
Follow-up 1
What do the three numbers in a version (e.g., 1.0.2) signify?
The three numbers in a version signify different levels of changes:
- MAJOR version: This number is incremented when there are incompatible changes in the API or functionality of the package.
- MINOR version: This number is incremented when new features are added in a backwards-compatible manner.
- PATCH version: This number is incremented when backwards-compatible bug fixes or patches are made to the package.
Follow-up 2
What is the significance of the caret (^) and tilde (~) symbols in the version number?
The caret (^) and tilde (~) symbols are used in the version number to specify the range of acceptable versions for a package.
- The caret (^) symbol allows updates to the most recent MINOR version while keeping the MAJOR version fixed. For example, ^1.2.3 means any version greater than or equal to 1.2.3 and less than 2.0.0.
- The tilde (~) symbol allows updates to the most recent PATCH version while keeping the MAJOR and MINOR versions fixed. For example, ~1.2.3 means any version greater than or equal to 1.2.3 and less than 1.3.0.
Follow-up 3
How does NPM handle version conflicts between different packages?
NPM uses a dependency resolution algorithm to handle version conflicts between different packages. When installing or updating packages, NPM analyzes the dependencies specified in the package.json file and tries to find a compatible set of versions for all dependencies.
If there is a conflict, NPM will attempt to resolve it by finding a version that satisfies the requirements of all packages. It may choose to update or downgrade certain packages to resolve the conflict.
In some cases, manual intervention may be required to resolve version conflicts by updating the package.json file or using specific version ranges for dependencies.
5. What is the purpose of the NPM registry?
The npm registry is the central, public database of JavaScript packages that the npm CLI talks to. When you npm install express, the CLI resolves the version, downloads the package tarball from the registry, and records it; when you npm publish, your package is uploaded there for others to use. It also stores each package's metadata, versions, and integrity hashes.
Points that round out the answer: the default is the public registry at registry.npmjs.org, but you can point npm at a private/alternate registry (GitHub Packages, Verdaccio, Artifactory, JFrog) via .npmrc — common for proprietary internal packages, often scoped (@myco/...). The registry's integrity hashes (recorded in package-lock.json) let npm verify downloads haven't been tampered with.
The security angle worth raising: because anyone can publish, the registry is a supply-chain attack surface (typosquatting, malicious or compromised packages). Mitigate with npm audit, lockfiles, pinned/audited versions, provenance, and tools like npm ci plus organizational scanning.
Follow-up 1
How can you publish a package to the NPM registry?
To publish a package to the NPM registry, you need to have an NPM account. Once you have an account, you can use the npm publish command in your package's directory. This command will create a new version of your package and upload it to the registry. Before publishing, make sure to update the version number in your package.json file to ensure proper versioning.
Follow-up 2
What are some best practices for maintaining a package in the NPM registry?
Here are some best practices for maintaining a package in the NPM registry:
- Keep your package up to date: Regularly update your package with bug fixes, new features, and security patches.
- Follow semantic versioning: Use semantic versioning to indicate the compatibility and impact of new releases.
- Write clear documentation: Provide clear and comprehensive documentation to help users understand how to use your package.
- Respond to issues and feedback: Monitor and respond to issues and feedback from users to improve your package.
- Use a version control system: Use a version control system like Git to track changes and collaborate with others on your package.
- Test your package: Implement automated tests to ensure the stability and reliability of your package.
- Consider using a linter: Use a linter to enforce code style and maintain consistency in your package's codebase.
Follow-up 3
How can you set a specific version of a package to be the default in the NPM registry?
In the NPM registry, there is no concept of a default version for a package. When users install a package without specifying a version, NPM will install the latest version available in the registry. However, you can use the npm deprecate command to mark a specific version of your package as deprecated. This will discourage users from installing that version and encourage them to use a newer version instead.
Live mock interview
Mock interview: Node Package Manager (NPM)
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.