I have been working on dep, a tiny dependency installer for Node.js.
It is not meant to replace npm, pnpm, or Yarn. Those tools are mature, powerful, and solve many real-world problems. dep is intentionally much smaller.
The goal is to explore a simple question:
How small can a useful Node.js package installer be?
This question is not new for dep.
Back in 2017, I wrote about the original philosophy behind the project in dep: a little Node.js dependency installer. At the time, I described the idea of a “module end-user”: someone who builds software with packages, but does not necessarily publish packages themselves.
For that user, the minimum useful feature set was:
- Install dependencies defined in
package.json - Lock dependencies for repeatable installs
- Run scripts defined in
package.json
In short: install, lock, and run.
That philosophy has not really changed. What has changed is the implementation around it.
The current answer is a tool that can:
- Install packages and resolve nested dependencies
- Write an npm-compatible
package-lock.jsonv3 - Run package scripts with
dep run <script> - Support npm-style workspaces
- Use zero runtime dependencies, built purely on the Node.js standard library
GitHub: github.com/depjs/dep
Why build another installer?
The interesting part of dep is not that it is another package manager.
Package installation is usually treated as something magical, huge, and difficult to understand. But at its core, a useful installer only needs to do a few things:
- Read
package.json - Resolve dependency versions
- Download package tarballs from the registry
- Extract them into
node_modules - Write a deterministic lockfile
- Run package scripts
- Link workspace packages
That is still not trivial, but it is small enough to reason about.
dep is an attempt to make that process readable and educational.
What dep supports today
dep currently focuses on a small, predictable subset of package-manager behavior:
dep install
dep lock
dep run test
It also supports npm-style workspaces:
{
"workspaces": ["packages/*"]
}
The lockfile format is compatible with npm's package-lock.json v3.
This means dep does not invent a new ecosystem format. It stays close to the existing npm ecosystem while keeping the implementation minimal.
Installing packages under the hood
At a high level, dep install orchestrates the following flow:
package.json
↓
Dependency metadata fetching
↓
Version resolution
↓
Tarball download and verification
↓
node_modules layout
↓
package-lock.json v3 generation
The challenge is not that each individual step is impossible.
The challenge is ensuring that all of them work together predictably without hiding the process behind too many abstractions.
For dep, the design goal is to keep each step explicit and understandable.
Writing package-lock.json v3
One of the most important decisions in dep is to write an npm-compatible lockfile.
A lockfile is not just an implementation detail. It is the contract between environments.
If two installs produce different dependency trees, debugging becomes painful very quickly.
By targeting package-lock.json v3, dep aims to provide repeatability and CI-friendliness without inventing a new format.
This also makes it easier to try dep in existing Node.js projects.
Zero runtime dependencies: the trade-offs
dep has zero runtime dependencies.
It relies entirely on built-in Node.js APIs such as fs, path, crypto, child_process, and others.
This is technically interesting for a few reasons.
Fewer moving parts
A dependency installer is the thing that installs dependencies.
So depending on a large dependency tree to install another dependency tree can feel recursive and strange.
With dep, there is no runtime dependency tree behind the installer itself.
Auditability
There is no hidden stack of packages behind the tool.
If something behaves unexpectedly, the code path is easier to inspect.
This matters especially for tooling that touches dependency installation, lockfiles, and project scripts.
Educational value
If you have ever wondered how package resolution, tarball extraction, lockfile generation, or workspace linking works, dep is intended to be small enough to read and experiment with.
Of course, zero dependencies does not mean zero complexity.
It often means implementing things directly that external libraries usually abstract away.
That is the core trade-off of the project.
What dep is not
dep is not trying to be a universal replacement for npm, pnpm, or Yarn.
You should keep using those tools for large production applications that depend on their full, optimized feature sets.
dep is ideal when you want:
- A minimal dependency installer
- An npm-compatible lockfile
- A readable codebase for learning how JavaScript tooling works
- A tool for small apps, experiments, or constrained environments
- A package installer that uses only the Node.js standard library at runtime
In that sense, dep is closer to a tiny npm-compatible installer than a full package manager.
Try it out
You can check out the source, open issues, or contribute here:
dep install
dep run test
If you are interested in Node.js tooling, lockfile internals, workspace behavior, or dependency resolution edge cases, I would love to hear your thoughts.
What is your favorite or least favorite part of how modern package managers handle dependencies?













