Package Managers Comparison Cheat Sheet
Side-by-side reference comparing common OS and language package managers, their install/update/remove syntax, and key configuration files.
Linux OS Package Managers
Core commands for apt (Debian/Ubuntu), dnf (Fedora/RHEL), and pacman (Arch).
# apt (Debian/Ubuntu)sudo apt update # Refresh package indexsudo apt install nginx # Install packagesudo apt remove nginx # Remove, keep configssudo apt purge nginx # Remove including configssudo apt upgrade # Upgrade all packages# dnf (Fedora/RHEL/CentOS Stream)sudo dnf install nginxsudo dnf remove nginxsudo dnf upgrade --refreshsudo dnf list installed# pacman (Arch Linux)sudo pacman -Syu # Sync + full system upgradesudo pacman -S nginx # Installsudo pacman -R nginx # Removesudo pacman -Rns nginx # Remove + unused deps + configs
Language Package Managers
Common install/add/remove commands for npm, pip, and cargo.
# npm (Node.js)npm install express # Install + save to dependenciesnpm install -D typescript # Save as devDependencynpm uninstall expressnpm ci # Clean install from package-lock.json# pip (Python)pip install requestspip install -r requirements.txtpip freeze > requirements.txt # Snapshot installed versionspip uninstall requests# cargo (Rust)cargo add serde # Add dependency to Cargo.tomlcargo build --releasecargo remove serde
Manifest & Lock Files
Where each manager stores dependency declarations and resolved versions.
- package.json / package-lock.json- npm's declared deps and exact resolved dependency tree
- requirements.txt / Pipfile.lock- pip's flat list, or Pipenv's locked resolution
- pyproject.toml / poetry.lock- Modern Python packaging metadata and Poetry's locked graph
- Cargo.toml / Cargo.lock- Rust crate manifest and pinned dependency versions
- go.mod / go.sum- Go module requirements and cryptographic checksums
- Gemfile / Gemfile.lock- Ruby Bundler's declared and resolved gem versions
- *.deb / *.rpm- Compiled Linux binary package formats used by apt/dpkg and dnf/rpm respectively
Semantic Versioning Ranges
How different ecosystems express acceptable version ranges.
- ^1.2.3 (npm)- Allow changes that don't modify the leftmost non-zero digit (up to <2.0.0)
- ~1.2.3 (npm)- Allow only patch-level changes (up to <1.3.0)
- >=1.2,<2.0 (pip)- Explicit inclusive/exclusive bounds in PEP 440 syntax
- 1.2.* (pip)- Wildcard match for any patch version within 1.2
- "1.2.3" (cargo default)- Cargo treats bare versions as caret requirements by default (^1.2.3)
- =1.2.3- Pin to an exact version, supported across npm, pip, and cargo
Resolver Strategies Compared
How npm, pip/poetry, and cargo actually resolve a dependency graph under the hood.
# npm >=7: nested + flattened hybrid resolver# - Deduplicates compatible versions into a single top-level node_modules entry# - Falls back to nested node_modules/<pkg>/node_modules/<dep> on conflictsnpm ls express # Show resolved tree for a packagenpm dedupe # Re-flatten tree after incremental installs# pip: legacy resolver was greedy/first-match (pre 20.3); now backtrackingpip install --use-deprecated=legacy-resolver pkg # Old behavior (avoid)pip install pkg --dry-run # Preview resolution (pip >=22.2)# Poetry: SAT-based resolver, resolves the whole graph before writing lockpoetry lock --no-update # Re-solve without bumping versionspoetry show --tree # Visualize resolved dependency tree# Cargo: resolves via semver + a single global feature-unification passcargo tree -d # Show duplicate dependency versionscargo tree -e features # Show which crates enabled which features
Private Registries & Auth
Pointing each manager at a private/internal registry with scoped auth tokens.
# npm: scope a registry per-org and store a token (never commit this file)echo "@myorg:registry=https://npm.internal.example.com" >> .npmrcecho "//npm.internal.example.com/:_authToken=\${NPM_TOKEN}" >> .npmrc# pip: point at an internal index, keep PyPI as extra fallbackpip install --index-url https://pypi.internal.example.com/simple \ --extra-index-url https://pypi.org/simple mypkg# cargo: source replacement in .cargo/config.toml# [source.crates-io]# replace-with = "internal"# [source.internal]# registry = "sparse+https://cargo.internal.example.com/index/"cargo login --registry internal $CARGO_TOKEN
Strict Reproducible Installs (CI)
Flags that fail the build instead of silently drifting from the lock file.
# npm: fails if package.json and package-lock.json are out of syncnpm ci# pip: hash-checking mode requires every dependency pinned with a --hashpip install --require-hashes -r requirements.txt# poetry: verifies lock is consistent with pyproject.toml before installingpoetry check --lockpoetry install --sync # Also remove packages not in the lock# cargo: refuses to touch Cargo.lock, errors if it would need to changecargo build --lockedcargo install --locked cargo-audit
Supply-Chain Security Tooling
Auditing installed dependencies for known vulnerabilities and integrity issues per ecosystem.
- npm audit / npm audit fix- Scans the resolved tree against the GitHub Advisory Database and can auto-bump vulnerable transitive deps
- pip-audit- PyPA tool that checks installed packages or a requirements file against the PyPI/OSV vulnerability feed
- cargo audit- Checks Cargo.lock against the RustSec advisory database for known-vulnerable crates
- Sigstore / npm provenance- npm publish --provenance attaches a signed attestation linking a package to its CI build source
- SBOM export- npm sbom, cargo cyclonedx, and pip-audit --format cyclonedx-json generate software bill-of-materials manifests
- dependabot / renovate- Automated bots that open PRs bumping manifest versions when advisories or new releases are published
- package pinning by hash- pip's --hash and npm's integrity field in package-lock.json (sha512) prevent a compromised registry from serving swapped bytes
Monorepo Workspaces
Managing multiple internal packages from a single lock file with npm and cargo.
// package.json (npm/yarn/pnpm workspaces){ "name": "monorepo-root", "private": true, "workspaces": ["packages/*", "apps/*"]}// commands:// npm install --workspaces install deps for every workspace// npm run build -w packages/core run a script scoped to one workspace// npm ls -w packages/core --depth=0 list only that workspace's direct deps// Cargo.toml (cargo workspaces)// [workspace]// members = ["crates/*"]// resolver = "2"// cargo build --workspace build every member crate// cargo test -p my-crate test a single member
Always commit lock files (package-lock.json, poetry.lock, Cargo.lock) to version control — they guarantee reproducible installs across machines and CI, while manifest files alone only express intent, not resolution.