Frequently Asked Question

Why aren't pip, cargo, and npm system package managers?

pip, cargo, npm, gem, and friends are language package managers: they understand the dependency graph of one programming language, pull libraries from a language-specific registry (PyPI, crates.io, the npm registry), and install them somewhere the runtime can find, usually inside a per-project virtual environment or a per-user directory like ~/.local. They know nothing about the C libraries those packages need (e.g. libssl, libpq), and they do not coordinate with anything else on the machine.

The system package manager (apt, dnf, pacman) is responsible for the operating system as a whole: the kernel, init system, shell, every binary in /usr/bin, every configuration file in /etc. It treats those files as atomic units and refuses to let two packages claim the same path. Asking pip install to manage system Python is therefore dangerous: it can overwrite files owned by the distribution's Python package and leave the system manager unable to upgrade them. The fix, enforced by PEP 668 since 2022, is that distribution Python installs an "externally-managed" marker, and pip outside a virtual environment now refuses to touch it. Use the system manager for system things, and language managers, inside virtualenvs, Cargo.toml, package.json, for the projects that need them.

Further reading and video