
Dev Dependency Management
- 152 installs
- 73 repo stars
- Updated July 13, 2026
- vasilyu1983/ai-agents-public
Helps with ai & agent building tasks.
About
dev-dependency-management is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- dev-dependency-management
- AI & Agent Building
- AI-coding skill
Dev Dependency Management by the numbers
- 152 all-time installs (skills.sh)
- +10 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #3,352 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/vasilyu1983/ai-agents-public --skill dev-dependency-managementAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 152 |
|---|---|
| repo stars | ★ 73 |
| Last updated | July 13, 2026 |
| Repository | vasilyu1983/ai-agents-public ↗ |
What it does
Helps with ai & agent building tasks.
Files
Dependency Management — Production Patterns
Modern Best Practices (January 2026): Lockfile-first workflows, automated security scanning (Dependabot, Snyk, Socket.dev), semantic versioning, minimal dependencies principle, monorepo workspaces (pnpm, Nx, Turborepo), supply chain security (SBOM, AI BOM, Sigstore), reproducible builds, and AI-generated code validation.
---
When to Use This Skill
The agent should invoke this skill when a user requests:
- Adding new dependencies to a project
- Updating existing dependencies safely
- Resolving dependency conflicts or version mismatches
- Auditing dependencies for security vulnerabilities
- Understanding lockfile management and reproducible builds
- Setting up monorepo workspaces (pnpm, npm, yarn)
- Managing transitive dependencies and overrides
- Choosing between similar packages (bundle size, maintenance, security)
- Dependency version constraints and semantic versioning
- Dependency security best practices and supply chain security
- Troubleshooting "dependency hell" scenarios
- Package manager configuration and optimization
- Creating reproducible builds across environments
---
Quick Reference
| Task | Tool/Command | Key Action | When to Use |
|---|---|---|---|
| Install from lockfile | npm ci, poetry install, cargo build | Clean install, reproducible | CI/CD, production deployments |
| Add dependency | npm install <pkg>, poetry add <pkg> | Updates lockfile automatically | New feature needs library |
| Update dependencies | npm update, poetry update, cargo update | Updates within version constraints | Monthly/quarterly maintenance |
| Check for vulnerabilities | npm audit, pip-audit, cargo audit | Scans for known CVEs | Before releases, weekly |
| View dependency tree | npm ls, pnpm why, pipdeptree | Shows transitive dependencies | Debugging conflicts |
| Override transitive dep | overrides (npm), pnpm.overrides | Force specific version | Security patch, conflict resolution |
| Monorepo setup | pnpm workspaces, npm workspaces | Shared dependencies, cross-linking | Multi-package projects |
| Check outdated | npm outdated, poetry show --outdated | Lists available updates | Planning update sprints |
---
Decision Tree: Dependency Management
User needs: [Dependency Task]
├─ Adding new dependency?
│ ├─ Check: Do I really need this? (Can implement in <100 LOC?)
│ ├─ Check: Is it well-maintained? (Last commit <6 months, >10k downloads/week)
│ ├─ Check: Bundle size impact? (Use Bundlephobia for JS)
│ ├─ Check: Security risks? (`npm audit`, Snyk)
│ └─ If all checks pass → Add with `npm install <pkg>` → Commit lockfile
│
├─ Updating dependencies?
│ ├─ Security vulnerability? → `npm audit fix` → Test → Deploy immediately
│ ├─ Routine update?
│ ├─ Patch versions → `npm update` → Safe, do frequently
│ ├─ Minor/major → Check CHANGELOG → Test in staging → Update gradually
│ └─ All at once → [FAIL] RISKY → Update in batches instead
│
├─ Dependency conflict?
│ ├─ Transitive dependency issue?
│ ├─ View tree: `npm ls <package>`
│ ├─ Use overrides sparingly: `overrides` in package.json
│ └─ Document why override is needed
│ └─ Peer dependency mismatch?
│ └─ Check version compatibility → Update parent or child
│
├─ Monorepo project?
│ ├─ Use pnpm workspaces (recommended default)
│ ├─ Shared deps → Root package.json
│ ├─ Package-specific → Package directories
│ └─ Use Nx or Turborepo for task caching
│
└─ Choosing package manager?
├─ New JS project → **pnpm** (recommended default) or **Bun** (often faster; verify ecosystem maturity)
├─ Enterprise monorepo → **pnpm** (mature workspace support)
├─ Speed-focused experimentation → **Bun** (verify ecosystem maturity)
├─ Existing npm project → Migrate to pnpm or stay (check team preference)
├─ Python → **uv** (fast), Poetry (mature), pip+venv (simple)
└─ Data science → **conda** or **uv** (faster environment setup)---
Navigation: Core Patterns
Lockfile Management
[`references/lockfile-management.md`](references/lockfile-management.md)
Lockfiles ensure reproducible builds by recording exact versions of all dependencies (direct + transitive). Essential for preventing "works on my machine" issues.
- Golden rules (always commit, never edit manually, regenerate on changes)
- Commands by ecosystem (npm ci, poetry install, cargo build)
- Troubleshooting lockfile conflicts
- CI/CD integration patterns
Semantic Versioning (SemVer)
[`references/semver-guide.md`](references/semver-guide.md)
Understanding version constraints (^, ~, exact) and how to specify dependency ranges safely.
- SemVer format (MAJOR.MINOR.PATCH)
- Version constraint syntax (caret, tilde, exact)
- Recommended strategies by project type
- Cross-ecosystem version management
Dependency Security Auditing
[`references/security-scanning.md`](references/security-scanning.md)
Automated security scanning, vulnerability management, and supply chain security best practices.
- Automated tools (Dependabot, Snyk, GitHub Advanced Security)
- Running audits (npm audit, pip-audit, cargo audit)
- CI integration and alert configuration
- Incident response workflows
Dependency Selection
[`references/dependency-selection-guide.md`](references/dependency-selection-guide.md)
Deciding whether to add a new dependency and choosing between similar packages.
- Minimal dependencies principle (best dependency is the one you don't add)
- Evaluation checklist (maintenance, bundle size, security, alternatives)
- Choosing between similar packages (comparison matrix)
- When to reject a dependency
Update Strategies
[`references/update-strategies.md`](references/update-strategies.md)
Keeping dependencies up to date safely while minimizing breaking changes and security risks.
- Update strategies (continuous, scheduled, security-only)
- Safe update workflow (check outdated, categorize risk, test, deploy)
- Automated update tools (Dependabot, Renovate, npm-check-updates)
- Handling breaking changes and rollback plans
Monorepo Management
[`references/monorepo-patterns.md`](references/monorepo-patterns.md)
Managing multiple related packages in a single repository with shared dependencies.
- Workspace tools (pnpm, npm, yarn workspaces)
- Monorepo structure and organization
- Build optimization (Nx, Turborepo)
- Versioning and publishing strategies
Transitive Dependencies
[`references/transitive-dependencies.md`](references/transitive-dependencies.md)
Dealing with dependencies of your dependencies (indirect dependencies).
- Viewing dependency trees (npm ls, pnpm why, pipdeptree)
- Resolving transitive conflicts (overrides, resolutions, constraints)
- Security risks and version conflicts
- Best practices (use sparingly, document, test)
Ecosystem-Specific Guides
[`references/ecosystem-guides.md`](references/ecosystem-guides.md)
Language and package-manager-specific best practices.
- Node.js (npm, yarn, pnpm comparison and best practices)
- Python (pip, poetry, conda)
- Rust (cargo), Go (go mod), Java (maven, gradle)
- PHP (composer), .NET (nuget)
Anti-Patterns
[`references/anti-patterns.md`](references/anti-patterns.md)
Common mistakes to avoid when managing dependencies.
- Critical anti-patterns (not committing lockfiles, wildcards, ignoring audits)
- Dangerous anti-patterns (never updating, deprecated packages)
- Moderate anti-patterns (overusing overrides, ignoring peer deps)
Container Dependency Patterns
[`references/container-dependency-patterns.md`](references/container-dependency-patterns.md)
Managing dependencies in containerized environments (Docker, OCI).
- Multi-stage builds, layer caching, base image selection
- Runtime vs build dependencies, image scanning, reproducible images
Version Conflict Resolution
[`references/version-conflict-resolution.md`](references/version-conflict-resolution.md)
Systematic approaches to resolving dependency version conflicts.
- Diamond dependency problems, resolution algorithms by ecosystem
- Override strategies, compatibility matrices, migration paths
License Compliance
[`references/license-compliance.md`](references/license-compliance.md)
Open-source license management and compliance automation.
- License compatibility matrix, copyleft vs permissive, SPDX identifiers
- Automated scanning (FOSSA, license-checker), policy enforcement in CI
---
Navigation: Templates
Node.js
[`assets/nodejs/`](assets/nodejs/)
- `package-json-template.json` - Production-ready package.json with best practices
npmrc-template.txt- Team configuration for npm- `pnpm-workspace-template.yaml` - Monorepo workspace setup
Python
[`assets/python/`](assets/python/)
- `pyproject-toml-template.toml` - Poetry configuration with best practices
Automation
[`assets/automation/`](assets/automation/)
- `dependabot-config.yml` - GitHub Dependabot configuration
- `renovate-config.json` - Renovate Bot configuration
- `audit-checklist.md` - Security audit workflow
- [`template-supply-chain-security.md`](assets/automation/template-supply-chain-security.md) - NEW SBOM, provenance, vulnerability management
- `template-dependency-upgrade-playbook.md` - Upgrade batching, rollout, rollback
- `template-sbom-vuln-triage-checklist.md` - SBOM mapping + vulnerability triage
---
Supply Chain Security
[assets/automation/template-supply-chain-security.md](assets/automation/template-supply-chain-security.md) — Production-grade dependency security covering SBOM generation (CycloneDX/SPDX), provenance and attestation (SLSA, Sigstore), vulnerability management SLAs, upgrade playbooks, and EU Cyber Resilience Act requirements.
Key rules: generate SBOM per release, sign artifacts (Sigstore/cosign), run audit scans in CI, fix critical CVEs within 24 hours, use npm ci (never npm install) in pipelines, batch non-security updates by risk level.
Related templates:
- assets/automation/template-dependency-upgrade-playbook.md
- assets/automation/template-sbom-vuln-triage-checklist.md
---
AI-Generated Dependency Risks
WARNING: AI coding agents can introduce vulnerable or non-existent packages at scale (Endor Labs, 2025).
The Problem
AI tools accelerate coding but introduce supply chain risks:
- Hallucinated packages — AI suggests packages that don't exist (typosquatting vectors)
- Vulnerable dependencies — AI recommends outdated or CVE-affected versions
- Unnecessary dependencies — AI over-relies on packages for simple tasks
Best Practices
| Do | Don't |
|---|---|
| Treat AI-generated code as untrusted third-party input | Blindly accept AI dependency suggestions |
| Enforce same SAST/SCA scanning for AI-generated code | Skip security review for "AI-written" code |
| Verify all AI-suggested packages actually exist | Trust AI to know current package versions |
| Integrate security tools into AI workflows (MCP) | Allow AI to add dependencies without review |
| Vet MCP servers as part of supply chain | Use unvetted AI integrations |
Validation Checklist
Before accepting AI-suggested dependencies:
- [ ] Package exists on registry (npm, PyPI, crates.io)
- [ ] Package name is spelled correctly (no typosquatting)
- [ ] Version is current and maintained
- [ ]
npm audit/pip-auditshows no vulnerabilities - [ ] Weekly downloads >1000 (established package)
- [ ] Last commit <6 months (actively maintained)
---
Optional: AI/Automation
Note: AI assists with triage but security decisions need human judgment.
- Automated PR triage — Categorize dependency updates by risk
- Changelog summarization — Summarize breaking changes in updates
- Vulnerability correlation — Link CVEs to affected packages
Bounded Claims
- AI cannot determine business risk acceptance
- Automated fixes require security team review
- Vulnerability severity context needs human validation
---
Quick Decision Matrix
| Scenario | Recommendation |
|---|---|
| Adding new dependency | Check Bundlephobia, npm audit, weekly downloads, last commit |
| Updating dependencies | Use npm outdated, update in batches, test in staging |
| Security vulnerability found | Use npm audit fix, review CHANGELOG, test, deploy immediately |
| Monorepo setup | Use pnpm workspaces or Nx/Turborepo for build caching |
| Transitive conflict | Use overrides sparingly, document why, test thoroughly |
| Choosing JS package manager | pnpm (fastest, disk-efficient), Bun (7× faster), npm (most compatible) |
| Python environment | uv (10-100× faster), Poetry (mature), pip+venv (simple), conda (data science) |
---
Core Principles
1. Always Commit Lockfiles
Lockfiles ensure reproducible builds across environments. Never add them to .gitignore.
Exception: Don't commit Cargo.lock for Rust libraries (only for applications).
2. Use Semantic Versioning
Use caret (^) for most dependencies, exact versions for mission-critical, avoid wildcards (*). See `references/semver-guide.md` for constraint syntax and strategies.
3. Audit Dependencies Regularly
Run npm audit / pip-audit / cargo audit weekly; fix critical vulnerabilities immediately. See `references/security-scanning.md`.
4. Minimize Dependencies
The best dependency is the one you don't add. Ask: Can I implement this in <100 LOC? See `references/dependency-selection-guide.md`.
5. Update Regularly
Update monthly or quarterly in batches — do not update all at once. See `references/update-strategies.md`.
6. Use Overrides Sparingly
Only override transitive dependencies for security patches or conflicts. Document why in a comment (// CVE-2023-xxxxx fix). See `references/transitive-dependencies.md`.
---
Related Skills
For complementary workflows and deeper dives:
- `dev-api-design` - API versioning strategies, dependency injection patterns
- `dev-git-workflow` - Git workflows for managing lockfile conflicts, branching strategies
- `qa-testing-strategy` - Testing strategies for dependency updates, integration testing
- `software-security-appsec` - OWASP Top 10, cryptography standards, authentication patterns
- `ops-devops-platform` - CI/CD pipelines, Docker containerization, DevSecOps, deployment automation
- `docs-codebase` - Documenting dependency choices, ADRs, changelogs
---
External Resources
See `data/sources.json` for curated resources:
- Package managers: npm, pnpm, Yarn, pip, Poetry, Cargo, Go modules, Maven, Composer
- Semantic versioning: SemVer spec, version calculators, constraint references
- Security tools: Snyk, Dependabot, GitHub Advanced Security, OWASP Dependency-Check, pip-audit, cargo-audit, Socket.dev, Renovate
- Lockfile management: Official docs for package-lock.json, poetry.lock, Cargo.lock, pnpm-lock.yaml
- Monorepo tools: pnpm workspaces, npm workspaces, Yarn workspaces, Nx, Turborepo, Lerna, Bazel
- Analysis tools: Bundlephobia, npm-check-updates, depcheck, pipdeptree, cargo tree
- Supply chain security: SLSA framework, SBOM (CISA), Sigstore, npm provenance, OpenSSF Scorecard
- Best practices: npm/Poetry/Cargo guides, ACM Queue articles, dependency hell references
- Version management: nvm, pyenv, rustup, asdf
- Learning resources: npm guides, Python Packaging User Guide, Rust Book, Monorepo.tools
---
Usage Notes
For Codex / Claude Code:
- Use this skill when users need dependency management guidance
- Reference specific resources based on the task (lockfiles, security, updates)
- Provide ecosystem-specific guidance (Node.js, Python, Rust)
- Always recommend security audits and reproducible builds
- Encourage minimal dependencies and regular updates
- Link to templates for common configurations
Best Practices:
- Always commit lockfiles (except Cargo.lock for libraries)
- Use semantic versioning (caret for most deps, exact for critical)
- Audit dependencies weekly (
npm audit,pip-audit,cargo audit) - Update dependencies monthly or quarterly (not all at once)
- Choose package manager based on project needs (pnpm for speed, Poetry for Python apps)
- Document dependency choices in ADRs (Architecture Decision Records)
---
Success Criteria: Dependencies are minimal, well-maintained, secure, reproducible across environments, and regularly audited for vulnerabilities.
---
Trend Awareness Protocol
IMPORTANT: When users ask recommendation questions about package managers, dependency tools, or supply chain security, you MUST use WebSearch to check current trends before answering.
Trigger Conditions
- "What's the best package manager for [ecosystem]?"
- "What should I use for [dependency management/security]?"
- "What's the latest in dependency management?"
- "Current best practices for [npm/pnpm/Poetry]?"
- "Is [tool/approach] still relevant in 2026?"
- "[pnpm] vs [npm] vs [yarn]?"
- "Best dependency security scanner?"
Required Searches
1. Search: "dependency management best practices 2026" 2. Search: "[specific tool] vs alternatives 2026" 3. Search: "supply chain security trends January 2026" 4. Search: "[package manager] features 2026"
What to Report
After searching, provide:
- Current landscape: What dependency tools are popular NOW
- Emerging trends: New package managers, security tools, or patterns gaining traction
- Deprecated/declining: Tools/approaches losing relevance or support
- Recommendation: Based on fresh data, not just static knowledge
Example Topics (verify with fresh search)
- Package managers (pnpm, npm, yarn, Poetry, uv for Python)
- Security scanning (Snyk, Dependabot, Socket.dev)
- Supply chain security (SBOM, Sigstore, SLSA)
- Monorepo tools (Nx, Turborepo, Bazel)
- Lockfile and reproducibility patterns
- Automated dependency updates (Renovate, Dependabot)
Ops Preflight: Dependency and Toolchain Health (for LLM Agents)
Run this before build/test/edit loops to prevent avoidable churn such as next: command not found.
# 1) Runtime + package manager sanity
node -v
npm -v
# 2) Lockfile and install mode
ls -1 package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null
test -d node_modules || npm ci
# 3) Verify framework binaries resolve
npx next --version 2>/dev/null || echo "next missing"
npx eslint --version 2>/dev/null || echo "eslint missing"
# 4) Surface dependency graph issues early
npm ls --depth=0Remediation Rules
- If binary missing: install from lockfile, do not ad-hoc install random versions.
- If lockfile drift detected: re-install using project standard tool (
npm ci,pnpm install --frozen-lockfile, etc). - If peer dependency conflict appears, fix root cause before continuing broad edits.
- Cache these checks at session start for long agent runs.
Fact-Checking
- Use web search/web fetch to verify current external facts, versions, pricing, deadlines, regulations, or platform behavior before final answers.
- Prefer primary sources; report source links and dates for volatile information.
- If web access is unavailable, state the limitation and mark guidance as unverified.
Dependency Audit Checklist
Use this checklist when auditing project dependencies for security, maintainability, and optimization.
Pre-Audit Information Gathering
- [ ] Document current state
# Node.js
npm ls --depth=0 > dependencies-snapshot.txt
npm outdated > outdated.txt
npm audit > audit-report.txt
# Python
pip list > requirements-current.txt
poetry show --outdated > outdated.txt
pip-audit > audit-report.txt
# Rust
cargo tree --depth=1 > dependencies-snapshot.txt
cargo outdated > outdated.txt
cargo audit > audit-report.txt- [ ] Identify direct vs transitive dependencies
- Direct: Listed in package.json/pyproject.toml/Cargo.toml
- Transitive: Dependencies of dependencies
- [ ] Check lockfile status
- [ ] Lockfile exists and committed to git
- [ ] Lockfile is in sync with package manifest
- [ ] No merge conflicts in lockfile
Security Audit
Vulnerability Scanning
- [ ] Run automated security audit
# Node.js
npm audit --audit-level=moderate
# Python
pip-audit
# or
safety check
# Rust
cargo audit- [ ] Review vulnerability report
- [ ] Note severity levels (critical, high, moderate, low)
- [ ] Identify affected dependencies
- [ ] Check if fixes are available
- [ ] Document any accepted risks
- [ ] Check for known supply chain attacks
- [ ] Review package maintainer changes
- [ ] Check for suspicious package names (typosquatting)
- [ ] Verify package integrity (checksums, signatures)
Automated Security Tools
- [ ] Enable Dependabot/Renovate
- [ ] Configure
.github/dependabot.yml - [ ] Set up auto-merge for patch updates (optional)
- [ ] Configure security alerts
- [ ] Snyk integration (if applicable)
- [ ] Connect repository to Snyk
- [ ] Review Snyk security reports
- [ ] Set up CI integration
- [ ] GitHub Advanced Security (if available)
- [ ] Enable dependency graph
- [ ] Enable Dependabot alerts
- [ ] Enable code scanning
Maintenance Audit
Dependency Health
- [ ] Check last update dates
# Node.js
npm info <package> time
# Python
poetry show <package>
# Rust
cargo search <package>- [ ] Evaluate maintenance status
- [ ] Last commit within 6 months? ([OK] Active)
- [ ] Last commit 6-12 months ago? ([WARNING] Slow)
- [ ] Last commit 12+ months ago? ([FAIL] Stale)
- [ ] Check issue/PR activity
- [ ] Open issues being addressed?
- [ ] Pull requests being reviewed?
- [ ] Responsive maintainers?
- [ ] Evaluate popularity
- [ ] Weekly downloads >10k? ([OK] Widely used)
- [ ] Weekly downloads 1k-10k? ([WARNING] Moderate)
- [ ] Weekly downloads <1k? ([FAIL] Low adoption)
Dependency Tree Analysis
- [ ] Identify large dependency trees
# Node.js
npm ls <package>
# Python
pipdeptree -p <package>
# Rust
cargo tree -p <package>- [ ] Look for duplicate dependencies
# Node.js
npm dedupe
# Check for multiple versions
npm ls <package> --depth=999- [ ] Check for circular dependencies
License Compliance
- [ ] Review licenses
# Node.js
npm install -g license-checker
license-checker --summary
# Python
pip install pip-licenses
pip-licenses
# Rust
cargo install cargo-license
cargo license- [ ] Verify license compatibility
- [ ] MIT, Apache 2.0, BSD: [OK] Permissive
- [ ] GPL, AGPL: [WARNING] Copyleft (check if compatible)
- [ ] Proprietary: [FAIL] Review terms carefully
Optimization Audit
Bundle Size Analysis (Frontend)
- [ ] Measure bundle impact
# Check individual package size
# Visit: https://bundlephobia.com/package/<package>@<version>
# Or use CLI
npm install -g bundlephobia
bundlephobia <package>- [ ] Identify heavy dependencies
- [ ] Note packages >100kb
- [ ] Check if tree-shaking is supported
- [ ] Consider lighter alternatives
Unused Dependencies
- [ ] Find unused dependencies
# Node.js
npm install -g depcheck
depcheck
# Python
pip install pipreqs
pipreqs --print- [ ] Remove unused dependencies
# Node.js
npm uninstall <package>
# Python
poetry remove <package>
# Rust
cargo remove <package>Version Constraint Review
- [ ] Review version constraints
- [ ] Too loose (
*,>=1.0.0): [FAIL] Unpredictable - [ ] Caret (
^1.2.3): [OK] Recommended - [ ] Tilde (
~1.2.3): [OK] Conservative - [ ] Exact (
1.2.3): [WARNING] Use for critical deps only
Update Strategy
Safe Update Process
- [ ] Update patch versions first
# Node.js
npm update
# Python
poetry update
# Rust
cargo update- [ ] Test after updates
- [ ] Run test suite
- [ ] Manual smoke testing
- [ ] Check for deprecation warnings
- [ ] Update minor versions
# Node.js (interactive)
npm install -g npm-check-updates
ncu -i --target minor
# Python
poetry update --with dev- [ ] Update major versions cautiously
- [ ] Read CHANGELOG and migration guides
- [ ] Update one major dependency at a time
- [ ] Test thoroughly
- [ ] Create rollback plan
Update Documentation
- [ ] Document changes
- [ ] Update CHANGELOG.md
- [ ] Note breaking changes
- [ ] Document any required code changes
- [ ] Commit with clear message
git add package.json package-lock.json
git commit -m "chore: update dependencies (axios 0.27 -> 1.0)"Monorepo-Specific Checks
Workspace Dependencies
- [ ] Check workspace dependency versions
- [ ] Ensure consistent versions across workspaces
- [ ] Hoist shared dependencies to root
- [ ] Use workspace protocol for internal packages
- [ ] Review workspace configuration
# pnpm
cat pnpm-workspace.yaml
# npm
cat package.json | jq '.workspaces'
# yarn
cat package.json | jq '.workspaces'Final Review
Summary Report
- [ ] Create audit summary
- Total dependencies (direct + transitive)
- Critical vulnerabilities found and status
- Outdated dependencies count
- Unused dependencies removed
- Bundle size changes (if applicable)
- Recommended actions
- [ ] Prioritize actions
- [RED] Critical: Security vulnerabilities, broken dependencies
- [YELLOW] Important: Outdated deps, maintenance issues
- [GREEN] Nice-to-have: Bundle size optimization, minor updates
Next Steps
- [ ] Schedule regular audits
- [ ] Monthly for production apps
- [ ] Quarterly for internal tools
- [ ] Before major releases
- [ ] Set up automation
- [ ] Enable Dependabot/Renovate
- [ ] Add audit script to CI/CD
- [ ] Configure automated security alerts
---
Quick Commands Reference
Node.js (npm)
npm audit # Security audit
npm audit fix # Auto-fix vulnerabilities
npm outdated # Check outdated packages
npm ls --depth=0 # List direct dependencies
npm update # Update to latest within constraintsPython (Poetry)
poetry show --outdated # Check outdated packages
poetry update # Update dependencies
pip-audit # Security audit
pipdeptree # Show dependency treeRust (Cargo)
cargo audit # Security audit
cargo outdated # Check outdated packages
cargo update # Update dependencies
cargo tree # Show dependency tree---
Audit Frequency Recommendations:
- Production apps: Monthly
- Internal tools: Quarterly
- Libraries: Before each release
- Security patches: Immediately when notified
# .github/dependabot.yml
# Automated dependency updates for GitHub repositories
# See: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
# Node.js dependencies (npm)
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/New_York"
open-pull-requests-limit: 5
reviewers:
- "security-team"
- "platform-team"
assignees:
- "tech-lead"
labels:
- "dependencies"
- "security"
- "automated"
commit-message:
prefix: "chore"
prefix-development: "chore"
include: "scope"
# Group minor and patch updates together
groups:
development-dependencies:
dependency-type: "development"
update-types:
- "minor"
- "patch"
production-dependencies:
dependency-type: "production"
update-types:
- "minor"
- "patch"
# Allow specific updates (overrides)
allow:
- dependency-name: "react"
- dependency-name: "next"
# Ignore specific dependencies
ignore:
- dependency-name: "lodash"
# Ignore updates to v5 (breaking changes)
versions: ["5.x"]
# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "ci"
- "dependencies"
# Docker dependencies
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
labels:
- "docker"
- "dependencies"
# Python dependencies (pip)
- package-ecosystem: "pip"
directory: "/backend"
schedule:
interval: "weekly"
labels:
- "python"
- "dependencies"
# Terraform modules
- package-ecosystem: "terraform"
directory: "/infrastructure"
schedule:
interval: "weekly"
labels:
- "infrastructure"
- "dependencies"
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
],
"description": "Renovate configuration for automated dependency updates",
"timezone": "America/New_York",
"schedule": [
"after 9am and before 5pm every weekday"
],
"labels": [
"dependencies",
"automated"
],
"assignees": [
"tech-lead"
],
"reviewers": [
"platform-team"
],
"prConcurrentLimit": 5,
"prHourlyLimit": 2,
"commitMessagePrefix": "chore:",
"commitMessageAction": "update",
"commitMessageTopic": "{{depName}}",
"commitMessageExtra": "to {{newVersion}}",
"semanticCommits": "enabled",
"rangeStrategy": "bump",
"packageRules": [
{
"description": "Group all non-major dependencies together",
"matchUpdateTypes": [
"minor",
"patch"
],
"groupName": "all non-major dependencies",
"groupSlug": "all-minor-patch"
},
{
"description": "Automatically merge patch updates for devDependencies",
"matchUpdateTypes": [
"patch"
],
"matchDepTypes": [
"devDependencies"
],
"automerge": true,
"automergeType": "pr",
"automergeStrategy": "squash"
},
{
"description": "Require manual review for major updates",
"matchUpdateTypes": [
"major"
],
"automerge": false,
"labels": [
"dependencies",
"major-update",
"needs-review"
]
},
{
"description": "Prioritize security updates",
"matchDatasources": [
"npm"
],
"matchUpdateTypes": [
"patch"
],
"matchCurrentVersion": "!/^0/",
"semanticCommitType": "fix",
"semanticCommitScope": "security"
},
{
"description": "Group React ecosystem updates",
"matchPackagePatterns": [
"^react",
"^@types/react"
],
"groupName": "React ecosystem"
},
{
"description": "Group Next.js ecosystem updates",
"matchPackagePatterns": [
"^next",
"^@next/",
"eslint-config-next"
],
"groupName": "Next.js ecosystem"
},
{
"description": "Group TypeScript ecosystem updates",
"matchPackagePatterns": [
"^typescript",
"^@typescript-eslint/"
],
"groupName": "TypeScript ecosystem"
},
{
"description": "Group testing libraries",
"matchPackagePatterns": [
"^jest",
"^@testing-library/",
"^vitest",
"^@vitest/"
],
"groupName": "Testing libraries"
},
{
"description": "Pin specific packages to avoid breaking changes",
"matchPackageNames": [
"webpack",
"babel-core"
],
"rangeStrategy": "pin"
},
{
"description": "Ignore certain packages",
"matchPackageNames": [
"moment"
],
"enabled": false
}
],
"vulnerabilityAlerts": {
"labels": [
"security",
"dependencies"
],
"assignees": [
"security-team"
],
"prPriority": 10
},
"lockFileMaintenance": {
"enabled": true,
"schedule": [
"before 5am on monday"
]
},
"separateMajorMinor": true,
"separateMultipleMajor": true,
"prCreation": "immediate",
"rebaseWhen": "behind-base-branch",
"platformAutomerge": false,
"ignoreTests": false,
"stopUpdatingLabel": "on-hold",
"dependencyDashboard": true,
"dependencyDashboardTitle": "Dependency Dashboard",
"configMigration": true,
"pinDigests": false,
"rollbackPrs": true,
"ignorePaths": [
"**/node_modules/**",
"**/dist/**",
"**/build/**"
],
"npm": {
"minimumReleaseAge": "3 days"
},
"postUpdateOptions": [
"npmDedupe"
],
"enabledManagers": [
"npm",
"dockerfile",
"github-actions",
"terraform"
]
}
Dependency Upgrade Playbook (Production)
Use this playbook to upgrade dependencies safely with predictable risk and minimal disruption.
---
Core
1) Policies (Set Once)
- Lockfiles are required and committed for all environments.
- CI uses lockfile installs (
npm ci,pip-sync/poetry install --sync,cargo build --locked). - Dependency updates are reviewed like code (tests required, changelog review for majors).
- Exceptions (pins/overrides) require an owner, a reason, and a removal date.
2) Upgrade Cadence (Default)
- Security fixes: within SLA (same-day for critical, <7 days for high).
- Patch updates: weekly.
- Minor updates: monthly (batched).
- Major updates: quarterly (planned, with canary/rollback).
3) Triage and Batching
Batch by risk to keep blast radius small:
- Batch A (low): patch versions, internal libs, dev-only tools.
- Batch B (medium): minor versions, runtime libs with good test coverage.
- Batch C (high): majors, auth/crypto, database drivers, build systems.
Rules:
- Max one high-risk upgrade per PR unless explicitly approved.
- Keep upgrade PRs reviewable (small diff + clear changelog summary).
4) Implementation Workflow
1. Create branch/PR: chore(deps): bump <group> 2. Update dependency + lockfile. 3. Run full test suite + linters + build. 4. Run security scan (SCA) and verify no new critical findings. 5. Validate runtime behavior in staging (or canary) for production dependencies. 6. Merge with clear rollback plan.
5) Rollback Strategy (Required)
- Ensure previous lockfile state is easily restorable (revert commit/PR).
- For containerized deploys, keep last-known-good artifact available.
- For DB migrations shipped with upgrades, document forward-only vs reversible.
6) Operability and Cost Control
- Cache dependencies in CI to reduce minutes and improve signal-to-noise.
- Run heavyweight tests only when relevant packages changed (path filters).
- Track build time regressions after major dependency upgrades.
---
Do / Avoid
Do
- Do batch upgrades by risk and keep PRs small
- Do read release notes for majors and security-sensitive packages
- Do treat overrides/pins as temporary debt with a removal date
- Do canary major upgrades when the dependency affects runtime behavior
Avoid
- Avoid floating ranges for production dependencies
- Avoid unreviewed transitive upgrades via lockfile churn
- Avoid upgrading everything at once (hard to debug and rollback)
- Avoid ignoring supply-chain signals (provenance, signatures, maintainer changes)
---
Optional: AI/Automation
- Auto-group upgrade PRs by ecosystem and risk (human-reviewed)
- Summarize changelogs and highlight breaking changes (human-validated)
- Draft upgrade PR descriptions with test evidence and rollback notes
Bounded Claims
- Automation cannot decide business risk acceptance.
- Changelog summaries can miss edge cases; validate against real tests.
SBOM & Vulnerability Triage Checklist
Use this checklist to make vulnerability handling repeatable, auditable, and fast.
---
Core
1) Intake
- [ ] Alert source: OSV / GHAS / Snyk / vendor advisory / internal pentest
- [ ] Package + version range affected
- [ ] Direct vs transitive dependency identified
- [ ] Runtime vs dev-only dependency confirmed
- [ ] SBOM available for the affected build artifact (commit SHA + build ID)
2) Exposure and Exploitability
- [ ] Is the vulnerable code path reachable in your product?
- [ ] Is the package shipped to production (or only used in CI/dev)?
- [ ] Is there a known exploit or active exploitation in the wild?
- [ ] Privileges required: unauthenticated / authenticated / admin / local only
- [ ] Data impact: confidentiality / integrity / availability
3) Severity and Prioritization
- [ ] Severity score captured (CVSS where available) and validated against your context
- [ ] Priority assigned based on exposure + exploitability (not score alone)
- [ ] Owner assigned (team + on-call contact)
- [ ] SLA applied (critical/high/medium/low) with due date
4) Remediation Options (Pick One)
- [ ] Upgrade to fixed version
- [ ] Patch via override/resolution (temporary; document removal date)
- [ ] Mitigate via configuration (disable feature / reduce surface)
- [ ] Isolate/contain (WAF rules, sandbox, permission tightening)
- [ ] Risk accept (requires explicit approval and a review date)
5) Verification
- [ ] Fix verified in dependency graph (lockfile,
npm ls,pipdeptree,cargo tree) - [ ] Build + tests passed (unit + integration as applicable)
- [ ] Rescan confirms vulnerability resolved
- [ ] Runtime verification done for critical issues (staging/canary)
6) Documentation and Follow-Up
- [ ] Incident log entry created (ticket ID, affected versions, fix commit)
- [ ] If secrets may be exposed, rotate and invalidate credentials
- [ ] If override used, create follow-up to remove it
- [ ] If root cause is process gap, add guardrail (policy, CI gate, training)
---
Do / Avoid
Do
- Do use SBOMs to answer “where is this running?” quickly
- Do treat transitive overrides as temporary and tracked debt
- Do combine vuln triage with rollout safety (canary, rollback, monitoring)
Avoid
- Avoid accepting risk without a time-bounded review date
- Avoid upgrading blindly without verifying the vulnerability is actually removed
- Avoid using severity score alone to set priority
---
Optional: AI/Automation
- Map alerts to SBOMs/builds and open tickets automatically (human-owned)
- Summarize advisory text into a 1-page triage brief (human-validated)
- Suggest remediation order by reachability and blast radius (human-approved)
Bounded Claims
- Automation cannot reliably determine runtime reachability without instrumentation.
- Approval, prioritization, and risk acceptance remain human decisions.
Supply Chain Security & SBOM Guide
Production-grade dependency security covering SBOM generation, provenance, signatures, and vulnerability management.
---
Software Bill of Materials (SBOM)
SBOM Generation Checklist
- [ ] SBOM format selected (CycloneDX or SPDX)
- [ ] SBOM generation integrated in CI/CD
- [ ] SBOM stored with release artifacts
- [ ] SBOM includes transitive dependencies
- [ ] SBOM versioned with each release
- [ ] SBOM accessible for security audits
SBOM Formats Comparison
| Format | Best For | Ecosystem | Spec |
|---|---|---|---|
| CycloneDX | Security, vulnerability tracking | OWASP | 1.5+ |
| SPDX | License compliance, legal | Linux Foundation | 2.3+ |
SBOM Generation Commands
# Node.js (CycloneDX)
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
# Python (CycloneDX)
pip install cyclonedx-bom
cyclonedx-py environment -o sbom.json
# Rust (CycloneDX)
cargo install cargo-cyclonedx
cargo cyclonedx -f json > sbom.json
# Go (CycloneDX)
go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@latest
cyclonedx-gomod mod -json -output sbom.json
# Universal (Syft - supports all ecosystems)
syft . -o cyclonedx-json > sbom.json
syft . -o spdx-json > sbom.spdx.jsonSBOM CI/CD Integration (GitHub Actions)
name: Generate SBOM
on:
release:
types: [published]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate SBOM with Syft
uses: anchore/sbom-action@v0
with:
format: cyclonedx-json
output-file: sbom.json
- name: Upload SBOM to release
uses: softprops/action-gh-release@v1
with:
files: sbom.json
- name: Attest SBOM provenance
uses: actions/attest-sbom@v1
with:
subject-path: ./dist/*
sbom-path: sbom.json---
Provenance & Attestation
SLSA Framework Levels
| Level | Requirements | Trust |
|---|---|---|
| SLSA 1 | Documented build process | Low |
| SLSA 2 | Version-controlled, hosted build | Medium |
| SLSA 3 | Hardened build platform, signed provenance | High |
| SLSA 4 | Hermetic, reproducible builds | Highest |
Provenance Attestation (Sigstore)
# Sign artifact with Sigstore (keyless)
cosign sign-blob --yes artifact.tar.gz > artifact.sig
# Verify signature
cosign verify-blob --signature artifact.sig artifact.tar.gz
# Generate SLSA provenance
slsa-provenance generate \
--artifact-path artifact.tar.gz \
--output-path provenance.jsonnpm Provenance (Native)
# Enable npm provenance (requires npm 9.5+)
npm publish --provenance
# Verify provenance
npm audit signaturesGitHub Artifact Attestations
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: ./dist/my-artifact.tar.gz---
Vulnerability Management
Vulnerability Triage Checklist
- [ ] CVSS score assessed
- [ ] Exploitability determined (PoC exists?)
- [ ] Exposure assessed (public-facing? internal?)
- [ ] Fix available? What version?
- [ ] Breaking changes in fix version?
- [ ] Workaround available?
- [ ] Risk acceptance documented (if not fixing)
Severity Response SLA
| Severity | CVSS | Response Time | Fix Deadline |
|---|---|---|---|
| Critical | 9.0-10.0 | < 4 hours | < 24 hours |
| High | 7.0-8.9 | < 24 hours | < 7 days |
| Medium | 4.0-6.9 | < 72 hours | < 30 days |
| Low | 0.1-3.9 | Next sprint | < 90 days |
Vulnerability Scanning Commands
# Node.js
npm audit
npm audit fix
npm audit --audit-level=high # CI gate
# Python
pip-audit
pip-audit --fix
# Rust
cargo audit
cargo audit fix
# Go
govulncheck ./...
# Universal (Trivy)
trivy fs .
trivy image myapp:latest
# Grype (alternative to Trivy)
grype dir:.
grype myapp:latestCI/CD Vulnerability Gate
name: Security Scan
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
exit-code: 1
severity: CRITICAL,HIGH
- name: npm audit
run: npm audit --audit-level=high---
Upgrade Playbook
Upgrade Workflow
1. Identify outdated packages
└─ npm outdated / poetry show --outdated / cargo outdated
2. Categorize by risk
├─ Patch: Low risk, batch weekly
├─ Minor: Medium risk, test in staging
└─ Major: High risk, dedicated sprint
3. Create upgrade branch
└─ git checkout -b deps/upgrade-[package]-[version]
4. Update lockfile
└─ npm install [package]@[version]
5. Run full test suite
└─ npm test && npm run e2e
6. Deploy to staging (canary)
└─ Monitor for 24h
7. Deploy to production
└─ Staged rollout if critical path
8. Document in changelogBatching Strategy
| Update Type | Batch Size | Frequency | Review |
|---|---|---|---|
| Security patches | All | Immediate | Automated |
| Patch versions | Up to 10 | Weekly | Quick review |
| Minor versions | Up to 5 | Bi-weekly | Full review |
| Major versions | 1 at a time | Quarterly | Deep review |
Rollback Procedure
# Git: Revert lockfile
git checkout HEAD~1 -- package-lock.json
npm ci
# Or: Pin to previous version
npm install [package]@[previous-version] --save-exact---
Pinning & Reproducibility
Lockfile Requirements
| Ecosystem | Lockfile | Commit? | CI Command |
|---|---|---|---|
| npm | package-lock.json | [OK] Yes | npm ci |
| pnpm | pnpm-lock.yaml | [OK] Yes | pnpm install --frozen-lockfile |
| Yarn | yarn.lock | [OK] Yes | yarn install --immutable |
| pip | requirements.txt + hashes | [OK] Yes | pip install -r requirements.txt --require-hashes |
| Poetry | poetry.lock | [OK] Yes | poetry install --no-root |
| Cargo | Cargo.lock | Apps: [OK], Libs: [FAIL] | cargo build --locked |
| Go | go.sum | [OK] Yes | go build (auto-verifies) |
Hash Pinning (Python)
# requirements.txt with hashes
requests==2.31.0 \
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1Generate hashes:
pip-compile --generate-hashes requirements.inVersion Constraints Best Practices
// package.json - Good
{
"dependencies": {
"express": "^4.18.2", // Caret: patches + minors
"lodash": "~4.17.21", // Tilde: patches only
"critical-lib": "1.2.3" // Exact: no updates without review
}
}
// Bad: Never use
{
"dependencies": {
"anything": "*", // BAD: Wildcard
"risky": ">=1.0.0", // BAD: Unbounded
"legacy": "latest" // BAD: Floating tag
}
}---
Do / Avoid
GOOD: Do
- Generate SBOM for every release
- Sign release artifacts (Sigstore/cosign)
- Run vulnerability scans in CI/CD
- Fix critical vulnerabilities within 24 hours
- Document risk acceptance for deferred fixes
- Use lockfiles for reproducible builds
- Batch non-security updates by risk level
- Verify npm package provenance
BAD: Avoid
- Publishing without SBOM
- Using unsigned packages in production
- Ignoring vulnerability scanner output
- Updating all dependencies at once
- Using wildcard version ranges
- Committing without updating lockfile
- Bypassing security gates "just this once"
- Trusting packages without provenance
---
Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
| No SBOM | Can't respond to supply chain attacks | Generate SBOM in CI/CD |
| Unsigned artifacts | Tampering undetectable | Sign with Sigstore |
| Audit ignored | Vulnerabilities ship to prod | Gate deployments on audit |
| Floating versions | Build not reproducible | Use lockfiles + exact versions |
| All-at-once updates | Hard to bisect regressions | Batch by risk level |
| npm install in CI | Non-deterministic | Use npm ci |
---
Optional: AI/Automation
Note: AI tools assist but require human judgment for security decisions.
Automated Triage
- CVSS enrichment with exploitability context
- Auto-categorization of vulnerability severity
- PR description generation for security updates
AI-Assisted Analysis
- Dependency changelog summarization
- Breaking change detection in major updates
- Risk scoring for transitive dependencies
Bounded Claims
- AI cannot determine business risk acceptance
- Automated fixes require security team review
- Vulnerability severity context needs human validation
---
Compliance Checklist
For Regulated Industries
- [ ] SBOM meets NTIA minimum elements
- [ ] Vulnerability disclosure process documented
- [ ] Third-party risk assessment performed
- [ ] License compliance verified (SPDX)
- [ ] Supply chain security policy documented
- [ ] Incident response plan includes supply chain
Regulatory References
- US Executive Order 14028: Requires SBOM for federal software
- EU Cyber Resilience Act: Mandates vulnerability handling
- PCI DSS 4.0: Third-party component inventory
- NIST SP 800-218: Secure software development
---
Related Templates
- audit-checklist.md — Security audit workflow
- dependabot-config.yml — Automated update PRs
- renovate-config.json — Renovate Bot setup
---
Last Updated: December 2025
---
Sources
- SLSA Framework — Supply chain security levels
- Sigstore — Keyless signing
- CycloneDX — SBOM standard
- SPDX — Software package data exchange
- npm Provenance
- OpenSSF Scorecard
# .npmrc - Team Configuration Template
# Copy to project root as .npmrc
# =============================================================================
# SECURITY
# =============================================================================
# Require package-lock.json for all installs
package-lock=true
# Strict SSL verification (never disable in production)
strict-ssl=true
# Audit packages on install
audit=true
# Audit level threshold (critical, high, moderate, low, info)
audit-level=high
# =============================================================================
# PERFORMANCE
# =============================================================================
# Use npm ci behavior by default (prefer offline, faster)
prefer-offline=true
# Cache location (customize for CI/CD)
# cache=/path/to/custom/cache
# Fetch retries for network issues
fetch-retries=3
fetch-retry-mintimeout=10000
fetch-retry-maxtimeout=60000
# =============================================================================
# REGISTRY
# =============================================================================
# Default registry (uncomment for private registry)
# registry=https://registry.npmjs.org/
# Scoped registry example (for private packages)
# @mycompany:registry=https://npm.mycompany.com/
# =============================================================================
# SAVE BEHAVIOR
# =============================================================================
# Save exact versions (no ^ or ~)
# save-exact=true
# Default save type (prod, dev, optional, peer)
save=true
# =============================================================================
# ENGINE STRICTNESS
# =============================================================================
# Fail if Node.js version doesn't match engines field
engine-strict=true
# =============================================================================
# SCRIPTS
# =============================================================================
# Allow dependency scripts by default; set ignore-scripts=true in CI for maximum security.
ignore-scripts=false
# For maximum security in CI, use:
# ignore-scripts=true
# =============================================================================
# LOGGING
# =============================================================================
# Log level (silent, error, warn, notice, http, timing, info, verbose, silly)
loglevel=warn
# =============================================================================
# CI/CD SPECIFIC
# =============================================================================
# For CI environments, consider these settings:
# prefer-offline=true
# audit=true
# audit-level=high
# ignore-scripts=true (if you don't need postinstall scripts)
# fund=false (disable funding messages)
# Disable funding messages
fund=false
# Disable update notifier
update-notifier=false
{
"name": "project-name",
"version": "1.0.0",
"description": "Project description",
"keywords": ["keyword1", "keyword2"],
"homepage": "https://github.com/username/project#readme",
"bugs": {
"url": "https://github.com/username/project/issues"
},
"license": "MIT",
"author": "Your Name <you@example.com>",
"repository": {
"type": "git",
"url": "git+https://github.com/username/project.git"
},
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
},
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest",
"test:coverage": "jest --coverage",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"type-check": "tsc --noEmit",
"audit": "npm audit --audit-level=moderate",
"audit:fix": "npm audit fix",
"outdated": "npm outdated",
"prepare": "husky install",
"clean": "rm -rf .next node_modules"
},
"dependencies": {
"next": "^14.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"@types/react": "^18.2.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.0.0",
"eslint-config-next": "^14.0.0",
"husky": "^8.0.0",
"jest": "^29.0.0",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"overrides": {},
"resolutions": {}
}
# pnpm-workspace.yaml
# Configuration for pnpm workspaces (monorepos)
# Documentation: https://pnpm.io/workspaces
packages:
# Include all packages in the packages directory
- 'packages/*'
# Include all apps in the apps directory
- 'apps/*'
# Include additional workspaces
- 'libs/*'
- 'tools/*'
# Exclude specific directories
- '!**/test/**'
- '!**/dist/**'
- '!**/node_modules/**'
# pyproject.toml - Modern Python project configuration
# Poetry documentation: https://python-poetry.org/docs/pyproject/
[tool.poetry]
name = "project-name"
version = "0.1.0"
description = "Project description"
authors = ["Your Name <you@example.com>"]
readme = "README.md"
license = "MIT"
homepage = "https://github.com/username/project"
repository = "https://github.com/username/project"
documentation = "https://project.readthedocs.io"
keywords = ["keyword1", "keyword2"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
[tool.poetry.dependencies]
python = "^3.12"
# Use caret (^) for flexible patch/minor updates
requests = "^2.31.0"
# Use tilde (~) for patch-only updates
fastapi = "~0.104.0"
# Use exact version for mission-critical deps
pydantic = "==2.5.0"
# Optional dependencies (install with: poetry install --extras "dev")
uvicorn = {version = "^0.24.0", optional = true}
[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
pytest-cov = "^4.1.0"
black = "^23.11.0"
ruff = "^0.1.6"
mypy = "^1.7.0"
pre-commit = "^3.5.0"
[tool.poetry.group.test.dependencies]
pytest-asyncio = "^0.21.0"
pytest-mock = "^3.12.0"
httpx = "^0.25.0"
[tool.poetry.extras]
dev = ["uvicorn"]
[tool.poetry.scripts]
# CLI commands
app = "project.cli:main"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
# Black configuration
[tool.black]
line-length = 100
target-version = ["py312", "py313"]
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.venv
| \.eggs
| build
| dist
)/
'''
# Ruff configuration (Python linter)
[tool.ruff]
line-length = 100
target-version = "py312"
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
]
ignore = ["E501"] # line too long (handled by black)
[tool.ruff.isort]
known-first-party = ["project"]
# Pytest configuration
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--strict-markers",
"--cov=project",
"--cov-report=term-missing",
"--cov-report=html",
"--cov-report=xml",
"-v",
]
# MyPy configuration
[tool.mypy]
python_version = "3.12"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
strict_equality = true
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
# Coverage configuration
[tool.coverage.run]
source = ["project"]
omit = ["tests/*", "**/__pycache__/*"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
]
{
"metadata": {
"title": "Dependency Management - Sources",
"description": "Primary sources for lockfiles, reproducible builds, vulnerability management, SBOMs, AI BOM, and supply-chain security",
"last_updated": "2026-01-17"
},
"package_managers": [
{
"name": "npm Documentation",
"url": "https://docs.npmjs.com/",
"description": "Official npm docs (install, lockfiles, workspaces, auditing)",
"add_as_web_search": true
},
{
"name": "pnpm Documentation",
"url": "https://pnpm.io/",
"description": "pnpm docs (workspaces, store, overrides)",
"add_as_web_search": true
},
{
"name": "Python Packaging User Guide (PyPA)",
"url": "https://packaging.python.org/",
"description": "Authoritative Python packaging guidance",
"add_as_web_search": true
},
{
"name": "Poetry Documentation",
"url": "https://python-poetry.org/docs/",
"description": "Poetry dependency management and lockfile usage",
"add_as_web_search": true
},
{
"name": "Cargo Book",
"url": "https://doc.rust-lang.org/cargo/",
"description": "Rust Cargo reference (lockfiles, features, publishing)",
"add_as_web_search": true
},
{
"name": "Go Modules Reference",
"url": "https://go.dev/ref/mod",
"description": "Go module system reference",
"add_as_web_search": true
},
{
"name": "uv Documentation (Astral)",
"url": "https://docs.astral.sh/uv/",
"description": "Fast Python package manager that can replace pip/virtualenv in many workflows; verify current feature parity vs Poetry for your use case",
"add_as_web_search": true
},
{
"name": "Bun Package Manager",
"url": "https://bun.sh/docs/cli/install",
"description": "JavaScript runtime with built-in package manager; verify current ecosystem maturity and compatibility for production use",
"add_as_web_search": true
}
],
"versioning_and_reproducibility": [
{
"name": "Semantic Versioning 2.0.0",
"url": "https://semver.org/",
"description": "SemVer specification",
"add_as_web_search": false
},
{
"name": "npm - package-lock.json",
"url": "https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json",
"description": "Official npm lockfile documentation",
"add_as_web_search": true
}
],
"vulnerability_management": [
{
"name": "Open Source Vulnerabilities (OSV)",
"url": "https://osv.dev/",
"description": "Open vulnerability database and API for OSS ecosystems",
"add_as_web_search": true
},
{
"name": "GitHub Advisory Database",
"url": "https://github.com/advisories",
"description": "Security advisories for open source vulnerabilities",
"add_as_web_search": true
}
],
"supply_chain_security": [
{
"name": "NIST SP 800-218 (SSDF)",
"url": "https://csrc.nist.gov/publications/detail/sp/800-218/final",
"description": "Secure Software Development Framework",
"add_as_web_search": true
},
{
"name": "SLSA v1.0 Specification",
"url": "https://slsa.dev/spec/v1.0/",
"description": "Supply-chain Levels for Software Artifacts (build provenance)",
"add_as_web_search": true
},
{
"name": "SPDX",
"url": "https://spdx.dev/",
"description": "SPDX SBOM standard (ISO/IEC)",
"add_as_web_search": true
},
{
"name": "CycloneDX",
"url": "https://cyclonedx.org/",
"description": "CycloneDX SBOM standard",
"add_as_web_search": true
},
{
"name": "Sigstore",
"url": "https://www.sigstore.dev/",
"description": "Signing and verifying software artifacts (cosign, fulcio, rekor)",
"add_as_web_search": true
},
{
"name": "OpenSSF Scorecard",
"url": "https://securityscorecards.dev/",
"description": "Automated security health metrics for open source projects",
"add_as_web_search": true
},
{
"name": "CISA SBOM Resources",
"url": "https://www.cisa.gov/sbom",
"description": "CISA SBOM minimum elements and federal requirements (2025 update)",
"add_as_web_search": true
},
{
"name": "EU Cyber Resilience Act (CRA)",
"url": "https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act",
"description": "EU regulation requiring SBOMs for software products (effective Dec 2027)",
"add_as_web_search": true
}
],
"tools": [
{
"name": "Syft (SBOM generator)",
"url": "https://github.com/anchore/syft",
"description": "Generate SBOMs from container images and filesystems",
"add_as_web_search": true
},
{
"name": "Grype (vulnerability scanner)",
"url": "https://github.com/anchore/grype",
"description": "Scan container images and filesystems for known vulnerabilities",
"add_as_web_search": true
},
{
"name": "Renovate",
"url": "https://docs.renovatebot.com/",
"description": "Automated dependency updates (highly configurable)",
"add_as_web_search": true
},
{
"name": "Dependabot",
"url": "https://github.com/dependabot",
"description": "Automated dependency updates and security alerts",
"add_as_web_search": true
},
{
"name": "Socket.dev",
"url": "https://socket.dev/",
"description": "Supply chain security platform detecting malicious packages",
"add_as_web_search": true
},
{
"name": "OWASP Dependency-Track",
"url": "https://dependencytrack.org/",
"description": "Continuous SBOM analysis platform for component risk identification",
"add_as_web_search": true
}
],
"ai_supply_chain": [
{
"name": "Endor Labs - State of Dependency Management 2025",
"url": "https://www.endorlabs.com/lp/state-of-dependency-management-2025",
"description": "Research on AI coding agent risks in software supply chain",
"add_as_web_search": true
},
{
"name": "AI BOM Concept (SD Times)",
"url": "https://sdtimes.com/ai/from-sbom-to-ai-bom-rethinking-supply-chain-security-for-ai-native-software/",
"description": "Extended SBOM for AI-native systems (models, datasets, training artifacts)",
"add_as_web_search": true
}
],
"optional_ai": [
{
"name": "Automated PR triage and summarization (Optional)",
"url": "https://docs.github.com/en/copilot",
"description": "Optional AI assistance for PR summaries (requires human review; product features vary)",
"add_as_web_search": true,
"optional": true
}
]
}
Dependency Management Anti-Patterns
When to Use: Learn what NOT to do when managing dependencies to avoid common pitfalls.
---
Overview
Anti-patterns are common practices that seem helpful but actually cause problems. This guide covers the most damaging dependency management anti-patterns and how to avoid them.
---
Critical Anti-Patterns (NEVER Do These)
1. Not Committing Lockfiles
BAD: Anti-Pattern:
# .gitignore
package-lock.json # BAD: DON'T IGNORE
pnpm-lock.yaml # BAD: DON'T IGNORE
poetry.lock # BAD: DON'T IGNORE
Cargo.lock # BAD: DON'T IGNORE (for apps)Why it's bad:
- Breaks reproducibility - different versions installed on different machines
- "Works on my machine" syndrome
- CI/production may get different versions than dev
- Hidden bugs from version mismatches
- Security vulnerabilities may appear unpredictably
Real-world disaster:
Developer: Uses axios@1.5.0 (no vulnerabilities)
CI: Installs axios@1.6.0 (has breaking change)
Production: Installs axios@1.4.0 (has CVE-2023-xxxxx)
Result: Production is vulnerable, CI tests don't catch itGOOD: Correct Approach:
# Commit lockfiles
git add package-lock.json pnpm-lock.yaml poetry.lock Cargo.lock go.sum
git commit -m "chore: add lockfiles for reproducibility"Exception: Don't commit Cargo.lock for Rust libraries (only for applications).
---
2. Using Wildcards (*) for Version Ranges
BAD: Anti-Pattern:
{
"dependencies": {
"express": "*",
"react": "*"
}
}Why it's bad:
- Completely unpredictable versions
- Breaking changes appear randomly
- No reproducibility even with lockfiles
- Production can break on any deploy
- Impossible to debug version-related issues
Real-world disaster:
Week 1: express@4.17.0 installed (works fine)
Week 2: express@5.0.0 released (breaking changes)
Week 3: New deploy pulls express@5.0.0
Result: Production crashes, team scrambles to fixGOOD: Correct Approach:
{
"dependencies": {
"express": "^4.18.0", // Allows patches and minors, not majors
"react": "~18.2.0" // Allows only patches
}
}When to use exact versions:
{
"dependencies": {
"critical-payment-lib": "1.2.3" // Exact version for mission-critical
}
}---
3. Manual Lockfile Editing
BAD: Anti-Pattern:
# Manually editing package-lock.json
vim package-lock.json
# Change version numbers by handWhy it's bad:
- Lockfile integrity broken
- Checksums won't match
- Installation will fail or reinstall wrong versions
- Package manager will overwrite your changes
- Corrupts dependency tree
GOOD: Correct Approach:
# Use package manager commands
npm install <package>@<version>
npm update
npm dedupe
# Let the package manager manage the lockfile---
4. Ignoring Security Audits
BAD: Anti-Pattern:
$ npm audit
found 23 vulnerabilities (5 high, 18 moderate)
# Developer: "I'll fix it later"
# (Never fixes it)Why it's bad:
- Known vulnerabilities exploited in production
- Data breaches, security incidents
- Compliance violations (SOC2, PCI-DSS)
- Legal liability
- Reputation damage
Real-world disaster:
Equifax breach (2017):
- Known vulnerability in Apache Struts
- Patch available for 2 months
- Never applied
- Result: 147 million records stolen, $700M+ in costsGOOD: Correct Approach:
# Run audit regularly
npm audit
# Fix automatically (safe)
npm audit fix
# Review and fix manually (risky fixes)
npm audit fix --force
# Set up automated alerts
# Use Dependabot, Snyk, or GitHub Advanced Security---
5. Adding Dependencies Without Review
BAD: Anti-Pattern:
# Developer sees a cool package on Twitter
npm install left-pad is-odd uppercase
# No review, no research, no questionsWhy it's bad:
- Supply chain attacks (malicious packages)
- Dependency bloat (hundreds of transitive deps)
- Bundle size explosion
- Security vulnerabilities
- Unmaintained packages
- License violations
Real-world disasters:
event-stream (2018):
- Popular npm package compromised
- Malicious code injected by new maintainer
- Stole Bitcoin wallet credentials
- Downloaded 8M times per week
left-pad (2016):
- 11-line package unpublished
- Broke thousands of projects
- Highlighted fragility of npm ecosystemGOOD: Correct Approach:
# Before adding ANY dependency:
1. Check last update (within 6 months?)
2. Check weekly downloads (>10k?)
3. Check GitHub issues (responsive maintainers?)
4. Check bundle size (bundlephobia.com)
5. Check dependency tree (npm ls <package>)
6. Check security (npm audit <package>)
7. Check license compatibility
8. Ask: Can I implement this in <100 LOC?
# Document decision
# Add to ADR (Architecture Decision Record)---
Dangerous Anti-Patterns (Avoid These)
6. Never Updating Dependencies
BAD: Anti-Pattern:
# Package.json from 2019
{
"dependencies": {
"express": "4.16.0", // 5 years old
"lodash": "4.17.11", // Known vulnerabilities
"moment": "2.24.0" // Deprecated library
}
}Why it's bad:
- Technical debt accumulates
- Security vulnerabilities pile up
- Breaking changes pile up (harder to update later)
- Incompatibility with modern tools
- Loss of community support
GOOD: Correct Approach:
# Update regularly (monthly or quarterly)
npm outdated
npm update
# Or use automated tools
# Dependabot, Renovate---
7. Using Deprecated Packages
BAD: Anti-Pattern:
{
"dependencies": {
"request": "^2.88.0", // Deprecated since 2020
"moment": "^2.29.0", // Maintenance mode
"gulp": "^3.9.0", // Use Gulp 4+
"node-sass": "^4.14.0" // Deprecated (use sass)
}
}Why it's bad:
- No security patches
- Incompatible with newer Node versions
- No bug fixes
- Community moves on
- Harder to hire developers familiar with old tools
GOOD: Correct Approach:
{
"dependencies": {
"axios": "^1.6.0", // Instead of request
"date-fns": "^2.30.0", // Instead of moment
"gulp": "^4.0.2", // Gulp 4+
"sass": "^1.69.0" // Instead of node-sass
}
}Check deprecation status:
npm outdated
npm view <package>
# Look for "DEPRECATED" warning---
8. Mixing Package Managers
BAD: Anti-Pattern:
# Project has both
package-lock.json # From npm
yarn.lock # From yarn
pnpm-lock.yaml # From pnpm
# Team uses different package managers
# Lockfiles conflictWhy it's bad:
- Conflicting lockfiles
- Inconsistent dependency resolution
- Different versions on different machines
- Merge conflicts in lockfiles
- Confusion for new team members
GOOD: Correct Approach:
# Choose ONE package manager
# Document in README.md
# Add to package.json
{
"packageManager": "pnpm@8.0.0",
"engines": {
"npm": "please-use-pnpm",
"yarn": "please-use-pnpm"
}
}---
9. Using --force or --legacy-peer-deps Without Understanding
BAD: Anti-Pattern:
# Error during npm install
$ npm install
npm ERR! peer dep missing: react@^18.0.0
# Developer: "I'll just force it"
$ npm install --force
# or
$ npm install --legacy-peer-depsWhy it's bad:
- Hides real problems
- May install incompatible versions
- Runtime errors in production
- Hard to debug later
- Breaks assumptions of libraries
GOOD: Correct Approach:
# Understand WHY the error occurred
npm ls react
# Fix the root cause
# Option 1: Update the dependency
npm update package-with-peer-dep
# Option 2: Install missing peer dependency
npm install react@^18.0.0
# Option 3: Use overrides (if necessary)
{
"overrides": {
"react": "18.2.0"
}
}
# Document why (if using --legacy-peer-deps)---
10. Not Using Virtual Environments (Python)
BAD: Anti-Pattern:
# Installing globally (Python)
sudo pip install flask
sudo pip install django
# System Python polluted
# Conflicts between projectsWhy it's bad:
- Different projects need different versions
- System Python gets corrupted
- Permission issues
- Can't reproduce environments
- Hard to deploy
GOOD: Correct Approach:
# Use virtual environments
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Or use poetry
poetry install---
Moderate Anti-Patterns (Be Careful)
11. Overusing Overrides
BAD: Anti-Pattern:
{
"overrides": {
"axios": "1.6.0",
"lodash": "4.17.21",
"express": "4.18.0",
"react": "18.2.0",
"typescript": "5.0.0",
"webpack": "5.88.0",
"...": "50 more overrides"
}
}Why it's bad:
- Hides real dependency issues
- May break packages that expect specific versions
- Hard to maintain
- Masks incompatibilities
- Makes debugging harder
GOOD: Correct Approach:
{
"overrides": {
"axios": "1.6.0" // Only 1-2 critical overrides
}
}
// Document WHY in README:
// - axios override: CVE-2023-xxxxx fix---
12. Ignoring Peer Dependency Warnings
BAD: Anti-Pattern:
$ npm install
npm WARN react-dom@18.2.0 requires a peer of react@^18.0.0
npm WARN react@17.0.0 is installed
# Developer: "It's just a warning, ignore it"Why it's bad:
- Runtime errors in production
- Incompatible API usage
- Subtle bugs
- Undefined behavior
GOOD: Correct Approach:
# Install the correct peer dependency
npm install react@^18.0.0
# Or check if library supports your version
npm info react-dom peerDependencies---
13. Committing node_modules/
BAD: Anti-Pattern:
# .gitignore missing node_modules/
git add node_modules/
git commit -m "add dependencies"Why it's bad:
- Massive repo size (100MB+)
- Slow git operations
- Platform-specific binaries break
- Conflicts on every change
- Defeats purpose of package.json
GOOD: Correct Approach:
# .gitignore
node_modules/
venv/
__pycache__/
target/ # Rust
vendor/ # Go (usually)
# Commit lockfiles instead
git add package-lock.json---
14. Using Development Dependencies in Production
BAD: Anti-Pattern:
{
"dependencies": {
"express": "^4.18.0",
"jest": "^29.0.0", // BAD: Should be devDependency
"eslint": "^8.0.0", // BAD: Should be devDependency
"typescript": "^5.0.0" // BAD: Should be devDependency
}
}Why it's bad:
- Bloated production bundles
- Slower deployments
- Higher memory usage
- Security surface area increased
GOOD: Correct Approach:
{
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"jest": "^29.0.0",
"eslint": "^8.0.0",
"typescript": "^5.0.0"
}
}Install production-only:
npm install --production
# or
npm ci --production---
Checklist: Avoiding Anti-Patterns
Before every dependency change:
- [ ] [OK] Commit lockfiles
- [ ] [OK] Use semantic versioning (not wildcards)
- [ ] [OK] Use package manager commands (not manual edits)
- [ ] [OK] Run security audit
- [ ] [OK] Review dependency before adding
- [ ] [OK] Update dependencies regularly
- [ ] [OK] Avoid deprecated packages
- [ ] [OK] Use one package manager
- [ ] [OK] Understand
--forcebefore using - [ ] [OK] Use virtual environments (Python)
- [ ] [OK] Minimize overrides
- [ ] [OK] Fix peer dependency warnings
- [ ] [OK] Never commit
node_modules/ - [ ] [OK] Separate dev and prod dependencies
---
Summary
The Top 5 Most Damaging Anti-Patterns:
1. Not committing lockfiles - Breaks reproducibility 2. *Using wildcards (``) - Unpredictable versions 3. Ignoring security audits - Exploitable vulnerabilities 4. Adding deps without review - Supply chain attacks 5. Never updating** - Technical debt accumulates
Remember: Dependency management requires discipline. Shortcuts today become disasters tomorrow.
---
Quick Reference: What NOT To Do
| [FAIL] DON'T | [OK] DO |
|---|---|
| Ignore lockfiles | Commit lockfiles to git |
Use wildcards (*) | Use semver ranges (^, ~) |
| Edit lockfiles manually | Use package manager commands |
Ignore npm audit | Fix vulnerabilities immediately |
| Add deps without review | Check bundle size, security, maintenance |
| Never update | Update monthly/quarterly |
| Use deprecated packages | Migrate to maintained alternatives |
| Mix package managers | Choose one, document in README |
Use --force blindly | Understand and fix root cause |
| Skip virtual envs (Python) | Always use venv/poetry |
| Overuse overrides | Only 1-2 critical overrides |
| Ignore peer dep warnings | Install correct versions |
Commit node_modules/ | Add to .gitignore |
| Mix dev/prod deps | Separate into correct categories |
---
Final Advice: When in doubt, follow the principle of least surprise. If something seems hacky or fragile, it probably is. Do it the right way the first time.
Container Dependency Patterns
Operational reference for managing dependencies in containerized environments — multi-stage builds, layer caching, base image selection, vulnerability scanning, and reproducible builds.
Freshness anchor: January 2026 — aligned with Docker Engine 27.x, BuildKit 0.17, Trivy 0.58, Grype 0.83, and OCI Image Spec v1.1.
---
Base Image Selection Decision Tree
What runtime do you need?
├── Static binary (Go, Rust)
│ └── Use distroless/static or scratch
├── Minimal runtime (Node.js, Python, Java)
│ ├── Need shell access for debugging?
│ │ ├── YES → Alpine variant (e.g., node:22-alpine)
│ │ └── NO → Distroless (e.g., gcr.io/distroless/nodejs22-debian12)
│ └── Need specific system libraries (native extensions)?
│ ├── YES → Debian slim (e.g., node:22-slim)
│ └── NO → Alpine variant
└── Complex system dependencies (ML, scientific computing)
└── Use Debian slim or Ubuntu LTS
└── Pin to specific version tag, never use :latestBase Image Comparison
| Base | Size (compressed) | Package Manager | Shell | CVE surface | Use when |
|---|---|---|---|---|---|
scratch | 0 MB | None | No | Minimal | Static binaries only |
distroless/static | ~2 MB | None | No | Very low | Go, Rust static binaries |
distroless/base | ~20 MB | None | No | Low | C/C++ with glibc |
alpine:3.21 | ~3 MB | apk | Yes (ash) | Low | General minimal containers |
debian:bookworm-slim | ~30 MB | apt | Yes (bash) | Medium | Native extensions needed |
ubuntu:24.04 | ~30 MB | apt | Yes (bash) | Medium | Complex dependency chains |
Alpine Gotchas Checklist
- [ ] Uses musl libc, not glibc — some native extensions may fail
- [ ] Python packages with C extensions may need
apk add build-base - [ ] DNS resolution differences (musl resolver) — test thoroughly
- [ ] No locales by default — add if needed for i18n
- [ ] Smaller community for troubleshooting vs Debian
---
Multi-Stage Build Patterns
Standard Multi-Stage Pattern
# ---- Build stage ----
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build
# ---- Production stage ----
FROM node:22-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
# Install production deps only
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force
# Copy built artifacts from builder
COPY --from=builder /app/dist ./dist
# Non-root user
RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -D appuser
USER appuser
EXPOSE 3000
CMD ["node", "dist/server.js"]Build vs Runtime Dependencies
| Category | Examples | Stage |
|---|---|---|
| Build tools | gcc, make, python3 (node-gyp) | Build stage only |
| Dev dependencies | jest, eslint, typescript | Build stage only |
| Build artifacts | compiled JS, binaries, bundled CSS | Copy to production stage |
| Runtime dependencies | express, pg, redis | Production stage |
| System runtime libs | libssl, libc | Production base image |
Multi-Stage Checklist
- [ ] Build dependencies NOT present in final image
- [ ] Dev dependencies NOT installed in production stage
- [ ] Only necessary artifacts copied from build stage
- [ ] Final stage uses minimal base image
- [ ] Final stage runs as non-root user
- [ ] npm/pip/apt caches cleaned in the same RUN layer
---
Layer Caching Optimization
Layer Ordering Rules
Most stable layers first → Least stable layers last
1. Base image (changes rarely)
2. System package installation (changes monthly)
3. Language runtime config (changes per-project)
4. Dependency manifests COPY (changes when deps update)
5. Dependency install RUN (cached if manifests unchanged)
6. Application source COPY (changes every commit)
7. Build command RUN (runs every commit)Caching Optimization Checklist
- [ ]
COPY package.json package-lock.json ./BEFORECOPY . . - [ ] Dependency install (
npm ci) in separate layer from source copy - [ ] System packages installed in single
RUNwith&&chaining - [ ]
.dockerignoreexcludes:node_modules,.git,dist,*.md, tests - [ ] BuildKit cache mounts used for package manager caches
BuildKit Cache Mounts
# Node.js - cache npm
RUN --mount=type=cache,target=/root/.npm \
npm ci --ignore-scripts
# Python - cache pip
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-compile -r requirements.txt
# Go - cache module downloads and build cache
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /app/server ./cmd/server
# Rust - cache cargo registry and build artifacts
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
cargo build --release.dockerignore Template
.git
.github
node_modules
dist
build
*.md
*.log
.env*
.vscode
.idea
tests
__tests__
coverage
docker-compose*.yml
Makefile---
Vulnerability Scanning
Tool Comparison
| Tool | Type | CI Integration | Database | License |
|---|---|---|---|---|
| Trivy | Image + FS + IaC | GitHub Actions, GitLab CI | Multiple (NVD, GHSA) | Apache 2.0 |
| Grype | Image + FS | GitHub Actions | Anchore feed | Apache 2.0 |
| Docker Scout | Image | Docker Desktop, CI | Docker advisory DB | Free tier |
| Snyk Container | Image | CI/CD, IDE | Snyk DB | Free tier |
Trivy Integration
# Scan a built image
trivy image --severity HIGH,CRITICAL myapp:latest
# Scan with exit code for CI gating
trivy image --exit-code 1 --severity CRITICAL myapp:latest
# Scan filesystem (lock files)
trivy fs --scanners vuln /app
# Scan and output SARIF for GitHub Security
trivy image --format sarif --output results.sarif myapp:latest
# Ignore unfixed vulnerabilities
trivy image --ignore-unfixed myapp:latestGrype Integration
# Scan an image
grype myapp:latest
# Fail on high/critical
grype myapp:latest --fail-on high
# Output JSON for processing
grype myapp:latest -o json > results.jsonScanning Pipeline Checklist
- [ ] Scan on every image build in CI
- [ ] Gate deployments on CRITICAL vulnerabilities (fail the build)
- [ ] HIGH vulnerabilities tracked as tickets, fixed within SLA
- [ ] Base image scanned separately from application layer
- [ ]
.trivyignoreor Grype config for accepted risks (with expiration dates) - [ ] Weekly scheduled scan of deployed images (catch new CVEs)
- [ ] SBOM generated and stored (
trivy image --format spdx-json)
Vulnerability SLA Reference
| Severity | Fix SLA | Action |
|---|---|---|
| CRITICAL | 24-48 hours | Immediate patch or mitigation |
| HIGH | 7 days | Prioritize in current sprint |
| MEDIUM | 30 days | Schedule in backlog |
| LOW | 90 days | Address during maintenance |
---
Reproducible Builds
Pinning Strategies
| What to Pin | How | Example |
|---|---|---|
| Base image | SHA256 digest | FROM node:22-alpine@sha256:abc123... |
| System packages | Version specifier | apk add --no-cache curl=8.5.0-r0 |
| Language deps | Lockfile | package-lock.json, poetry.lock |
| Build tools | Version in Dockerfile | ARG BUILDKIT_VERSION=0.17.0 |
Reproducibility Checklist
- [ ] Base images pinned to digest (not just tag)
- [ ] Lockfiles committed and used (
npm ci, notnpm install) - [ ]
--ignore-scriptsflag used during install (run scripts explicitly if needed) - [ ] No
curl | bashpatterns for installing tools (pin versions instead) - [ ]
apt-getuses--no-install-recommends - [ ] Build arguments used for version pins (visible, overridable)
- [ ] Timezone and locale set explicitly if needed
- [ ]
COPYuses specific paths, not.(avoids accidental inclusion)
Base Image Update Strategy
Is there a CRITICAL CVE in the base image?
├── YES → Update immediately
│ ├── Rebuild and test
│ └── Deploy within SLA
└── NO
├── Monthly: check for base image updates
├── Quarterly: evaluate major version bumps
└── Automate with Renovate/Dependabot
└── Auto-PR for digest updates
└── Manual review for major version changes---
Language-Specific Patterns
Node.js
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY . .
RUN npm run build && npm prune --production- Use
npm ci(notnpm install) for reproducibility npm prune --productionremoves dev deps after build- Set
NODE_ENV=productionin production stage
Python
FROM python:3.13-slim AS builder
WORKDIR /app
RUN pip install --no-cache-dir poetry==1.8.5
COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt -o requirements.txt --without-hashes
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
FROM python:3.13-slim
COPY --from=builder /install /usr/local
COPY . /app
WORKDIR /app- Use
poetry exportorpip-compilefor deterministic installs --prefix=/installallows clean copy of installed packages
Go
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /server ./cmd/server
FROM scratch
COPY --from=builder /server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/server"]CGO_ENABLED=0for static binary-ldflags="-s -w"strips debug info (smaller binary)scratchbase image for minimal surface
Rust
FROM rust:1.84-slim AS builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release
COPY src ./src
RUN touch src/main.rs && cargo build --release
FROM gcr.io/distroless/cc-debian12
COPY --from=builder /app/target/release/myapp /
ENTRYPOINT ["/myapp"]- Dummy
main.rstrick caches dependency compilation touchforces rebuild of application code only
---
Anti-Patterns
| Anti-Pattern | Problem | Fix |
|---|---|---|
Using :latest tag | Non-reproducible, unpredictable updates | Pin to version tag or SHA digest |
| Installing dev tools in production image | Larger image, bigger attack surface | Multi-stage build, copy artifacts only |
| Running as root | Security vulnerability | USER nonroot or USER 1001 |
COPY . . before dependency install | Busts cache on every code change | Copy manifests first, install, then copy source |
apt-get install without --no-install-recommends | Bloated image with unnecessary packages | Always use --no-install-recommends |
No .dockerignore | .git, node_modules copied into build context | Maintain .dockerignore |
Multiple RUN apt-get commands | Wasted layers, cache issues | Chain with && in single RUN |
| Ignoring vulnerability scan results | Known CVEs in production | Gate CI on CRITICAL, SLA for HIGH |
npm install instead of npm ci | Non-deterministic dependency resolution | Always use npm ci with lockfile |
| No health check | Orchestrator cannot detect unhealthy containers | Add HEALTHCHECK instruction |
---
Cross-References
dev-dependency-management/references/version-conflict-resolution.md— resolving conflicts in lockfilesdev-dependency-management/references/license-compliance.md— scanning container images for license issuessoftware-security-appsec/references/threat-modeling-guide.md— container threat modelsoftware-backend/references/nodejs-best-practices.md— Node.js containerization specificsqa-observability/references/log-aggregation-patterns.md— container logging patterns
Dependency Selection Guide
When to Use: Deciding whether to add a new dependency or choosing between similar packages.
---
Minimal Dependencies Principle
Every dependency added to your project increases:
- Attack surface area
- Bundle size
- Maintenance burden
- Supply chain risk
- Build complexity
Golden Rule: The best dependency is the one you don't add.
---
Questions to Ask Before Adding a Dependency
1. Do I Really Need This?
Can I implement this in <100 lines of code?
Many utility libraries can be replaced with simple native implementations:
// BAD: Don't add 'is-odd' package
const isOdd = require('is-odd')
// GOOD: Use simple function
const isOdd = (n) => n % 2 !== 0
// BAD: Don't add 'left-pad' package
const leftPad = require('left-pad')
// GOOD: Use native method
const leftPad = (str, len) => str.padStart(len, '0')
// BAD: Don't add 'axios' for simple requests
const axios = require('axios')
const data = await axios.get(url)
// GOOD: Use native fetch
const response = await fetch(url)
const data = await response.json()Native alternatives often exist:
| Instead of | Use Native |
|---|---|
moment | Intl.DateTimeFormat, Date |
lodash.debounce | Simple timeout wrapper |
uuid | crypto.randomUUID() (Node 14.17+) |
axios | fetch API |
is-array | Array.isArray() |
query-string | URLSearchParams |
2. Is This Package Well-Maintained?
Maintenance Checklist:
- [ ] Last commit within 6 months - Active development
- [ ] Active issue resolution - Check open/closed ratio
- [ ] Weekly downloads >10k - Community adoption
- [ ] Multiple maintainers - Bus factor > 1
- [ ] CI/Tests passing - Quality assurance
- [ ] Changelog maintained - Clear release notes
- [ ] Responsive to security issues - Check GitHub Security tab
Red Flags:
- [WARNING] No commits in 2+ years
- [WARNING] Low weekly downloads (<1000)
- [WARNING] No tests or CI
- [WARNING] Single maintainer with no recent activity
- [WARNING] Many open security issues
- [WARNING] No documentation or examples
Where to Check:
# View package metadata
npm info <package>
# Check GitHub activity
npm repo <package>
# View npm package page
npm home <package>3. What's the Dependency Tree Size?
View dependency tree:
npm ls <package> # Show dependency tree
npm info <package> # Show package metadata
pnpm why <package> # Show why package is installedExample output:
$ npm ls axios
myapp@1.0.0
└─┬ axios@1.6.0
├── follow-redirects@1.15.3
├── form-data@4.0.0
│ ├── asynckit@0.4.0
│ ├── combined-stream@1.0.8
│ │ └── delayed-stream@1.0.0
│ └── mime-types@2.1.35
│ └── mime-db@1.52.0
└── proxy-from-env@1.1.0Red Flags:
- Large dependency tree (>50 transitive deps)
- Circular dependencies
- Conflicting peer dependencies
- Multiple versions of same package
4. What's the Bundle Size Impact?
For JavaScript/TypeScript:
Use Bundlephobia to check:
- Minified size - Production bundle impact
- Minified + gzipped - Network transfer size
- Tree-shakeable - Can unused code be removed?
Command-line check:
# Check package size
npm info <package> size
# Compare with alternative
npm info date-fns size
npm info dayjs size
npm info moment sizeExample comparison:
| Package | Minified | Gzipped | Verdict |
|---|---|---|---|
moment | 229 kB | 71.6 kB | [FAIL] Too large |
date-fns | 78.4 kB | 13.4 kB | GOOD |
dayjs | 6.5 kB | 2.6 kB | [OK] Best |
Guidelines:
- <10 kB gzipped: [OK] Excellent
- 10-50 kB gzipped: [YELLOW] Acceptable
- >50 kB gzipped: [WARNING] Evaluate carefully
- >100 kB gzipped: [FAIL] Likely too large
5. What Are the Security Risks?
Security audit:
# Check for vulnerabilities
npm audit
npm audit --json | jq '.vulnerabilities'
# Check specific package
npm audit <package>
# Use third-party scanners
npx snyk testCheck vulnerability databases:
Red Flags:
- Critical/High severity CVEs in last 12 months
- Known supply chain attacks
- No security policy (
SECURITY.md) - No contact for security issues
6. Are There Better Alternatives?
Evaluation matrix:
| Criterion | Tool/Check |
|---|---|
| Popularity | npm registry, GitHub stars |
| Maintenance | Last commit, issue response time |
| Bundle Size | Bundlephobia |
| Performance | Benchmarks, real-world tests |
| Security | npm audit, Snyk |
| Documentation | README, website quality |
| API Design | TypeScript support, ease of use |
| Dependencies | npm ls, transitive count |
| License | Check LICENSE file |
---
Choosing Between Similar Packages
Step-by-Step Evaluation
1. Create comparison table:
| Criterion | Package A | Package B | Package C |
|---|---|---|---|
| Weekly downloads | 10M | 5M | 1M |
| Bundle size (gzipped) | 13 kB | 7 kB | 25 kB |
| Last update | 2 weeks | 1 month | 6 months |
| GitHub stars | 45k | 20k | 8k |
| Open issues | 150 | 50 | 300 |
| TypeScript support | [OK] | [OK] | [FAIL] |
| Tree-shakeable | [OK] | [OK] | [FAIL] |
| CVEs (last 12mo) | 0 | 0 | 2 |
2. Test API ergonomics:
Try each package in a sandbox:
// Package A
import { format } from 'date-fns'
format(new Date(), 'yyyy-MM-dd')
// Package B
import dayjs from 'dayjs'
dayjs().format('YYYY-MM-DD')
// Package C - Native
new Intl.DateTimeFormat('en-CA').format(new Date())3. Consider ecosystem fit:
- Does it work with your framework? (React, Vue, Angular)
- Does it support your build tools? (Vite, webpack, esbuild)
- Is it actively used in your stack's ecosystem?
4. Document your choice:
Create an Architecture Decision Record (ADR):
# ADR 001: Date Library Selection
## Status
Accepted
## Context
We need a date formatting/manipulation library for the user dashboard.
## Decision
Use `date-fns` over `dayjs` and `moment`.
## Rationale
- Tree-shakeable (import only what we use)
- TypeScript support (native types)
- 13 kB gzipped vs moment's 71 kB
- Active maintenance (weekly releases)
- No security issues in last 2 years
- Functional API fits our codebase style
## Alternatives Considered
- `moment`: Deprecated, too large
- `dayjs`: Smaller, but less mature ecosystem
- Native `Intl`: Insufficient for complex formatting needs
## Consequences
- Bundle size increase: +13 kB gzipped
- Team needs to learn date-fns API
- Migration path from moment already documented---
Real-World Examples
Example 1: Date Libraries (JavaScript)
| Library | Bundle Size | Downloads/week | Last Update | Verdict |
|---|---|---|---|---|
moment | 229 kB | 10M+ | Maintenance mode | [FAIL] Deprecated |
date-fns | 13 kB | 12M+ | Active | [OK] Recommended |
dayjs | 7 kB | 10M+ | Active | [OK] Lightweight alternative |
Native Intl | 0 kB | Native | N/A | [OK] Best (no dependency) |
Recommendation: Use native Intl for simple formatting, date-fns for complex needs.
Example 2: HTTP Clients (JavaScript)
| Library | Bundle Size | Downloads/week | TypeScript | Verdict |
|---|---|---|---|---|
axios | 14 kB | 50M+ | [OK] | GOOD (features-rich) |
got | 50 kB | 5M+ | [OK] | [YELLOW] Node.js only |
ky | 5 kB | 2M+ | [OK] | [OK] Lightweight |
Native fetch | 0 kB | Native | [OK] | [OK] Best (modern browsers) |
Recommendation: Use native fetch for simple requests, axios for complex needs (interceptors, retries).
Example 3: State Management (React)
| Library | Bundle Size | Learning Curve | Ecosystem | Verdict |
|---|---|---|---|---|
| Redux | 6 kB | High | Large | [OK] Enterprise apps |
| Zustand | 3 kB | Low | Growing | [OK] Simple apps |
| Jotai | 3 kB | Medium | Modern | [OK] Atomic state |
| Context API | 0 kB | Low | Native | [OK] Simple state |
Recommendation: Start with Context API, add Zustand for global state, Redux for complex apps only.
---
Checklist: Before Adding Any Dependency
Use this checklist for EVERY dependency you consider adding:
Necessity:
- [ ] Can I implement this in <100 lines of native code?
- [ ] Does a native alternative exist? (check MDN, language docs)
- [ ] Is this solving a real problem (not premature optimization)?
Maintenance:
- [ ] Last commit within 6 months?
- [ ] Active issue resolution?
- [ ] Weekly downloads >10k?
- [ ] Multiple maintainers?
- [ ] CI/tests passing?
Quality:
- [ ] Bundle size acceptable? (<50 kB gzipped)
- [ ] Dependency tree reasonable? (<20 transitive deps)
- [ ] TypeScript support? (if using TypeScript)
- [ ] Tree-shakeable? (for JS libraries)
- [ ] Good documentation?
Security:
- [ ] No critical/high CVEs in last 12 months?
- [ ] Has security policy (
SECURITY.md)? - [ ] Passed
npm audit/snyk test? - [ ] License compatible with project?
Alternatives:
- [ ] Compared 2-3 alternatives?
- [ ] Documented choice in ADR?
- [ ] Team reviewed decision?
---
When to REJECT a Dependency
Automatic Rejection Criteria:
1. Critical security vulnerability with no fix available 2. Abandoned package (no commits in 2+ years) 3. Incompatible license (GPL in proprietary project) 4. Massive bundle size (>100 kB for simple utility) 5. Better native alternative exists (e.g., fetch vs axios for simple GET) 6. Can implement in <50 lines of simple code
Example rejections:
// BAD: REJECT: 'is-odd' package (1 line native implementation)
// npm install is-odd
const isOdd = (n) => n % 2 !== 0
// BAD: REJECT: 'left-pad' package (1 line native)
// npm install left-pad
const leftPad = (str, len) => str.padStart(len, '0')
// BAD: REJECT: 'moment' (deprecated, 229 kB)
// Use date-fns (13 kB) or native Intl
// BAD: REJECT: 'request' (deprecated since 2020)
// Use axios or native fetch---
Summary
The Dependency Decision Tree:
Should I add this dependency?
├─ Can I implement in <100 LOC? → YES → Don't add
├─ Is there a native alternative? → YES → Use native
├─ Is it well-maintained? → NO → Don't add
├─ Bundle size acceptable? → NO → Find alternative
├─ Security audit clean? → NO → Don't add
└─ All checks pass → Add with caution, document choiceRemember: Every dependency is a liability. Add dependencies deliberately, not reflexively.
Dependency Management by Ecosystem
When to Use: Ecosystem-specific guidance for Node.js, Python, Rust, Go, and other language ecosystems.
---
Node.js (npm / yarn / pnpm / Bun)
Package Manager Comparison (January 2026)
| Feature | npm 11.x | yarn 4.x (Berry) | pnpm 10.x | Bun 1.3 |
|---|---|---|---|---|
| Speed | Slowest | Decent | Fast | Fastest (7× npm) |
| Disk Usage | High (duplicates) | PnP: None / Classic: High | Lowest (hard links) | Low (global cache) |
| Monorepo Support | Good (workspaces) | Good (workspaces) | Best (strict isolation) | Good (improving) |
| Security | Good (audit built-in) | Good | Good | Good |
| Ecosystem | Largest | Large | Large | Growing |
| Lockfile | package-lock.json | yarn.lock | pnpm-lock.yaml | bun.lock |
| Install Command | npm install | yarn install | pnpm install | bun install |
| CI Command | npm ci | yarn install --frozen-lockfile | pnpm install --frozen-lockfile | bun install --frozen-lockfile |
| Deterministic | Yes | Excellent (PnP) | Excellent | Yes |
Recommendations (January 2026):
- New projects: pnpm (fastest stable, best disk efficiency) or Bun (7× faster, production-ready)
- Enterprise monorepos: pnpm (most stable workspace support)
- Speed-focused experimentation: Bun (bleeding edge performance)
- Maximum compatibility: npm (most packages tested against it)
npm Best Practices
1. Use `npm ci` in CI/CD (not `npm install`):
# BAD: Bad (in CI)
npm install
# GOOD: Good (in CI)
npm ciWhy: npm ci installs from lockfile exactly, faster, and fails if package.json and lockfile are out of sync.
2. Enable `save-exact` for critical applications:
npm config set save-exact trueOr in .npmrc:
save-exact=trueEffect:
{
"dependencies": {
"express": "4.18.2" // Exact version (not ^4.18.2)
}
}3. Use `.npmrc` for team configuration:
# .npmrc (committed to git)
save-exact=false
package-lock=true
engine-strict=true
audit-level=moderate4. Configure private registry (optional):
registry=https://registry.npmjs.org/
@myorg:registry=https://npm.mycompany.com/5. Audit dependencies monthly:
# Check for vulnerabilities
npm audit
# Auto-fix non-breaking
npm audit fix
# Check specific package
npm view <package> vulnerabilities6. Use workspaces for monorepos:
{
"workspaces": [
"packages/*",
"apps/*"
]
}pnpm Best Practices
1. Use `pnpm` for speed and disk efficiency:
# Install pnpm globally
npm install -g pnpm
# Migrate from npm
pnpm import # Converts package-lock.json → pnpm-lock.yaml
# Install dependencies
pnpm install2. Configure workspaces:
# pnpm-workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
- '!**/test/**' # Exclude test directories3. Use filters for monorepo commands:
# Run script in specific package
pnpm --filter @myorg/ui build
# Run script in all packages
pnpm -r test
# Run script in changed packages only
pnpm --filter="...[origin/main]" test4. Enable strict peer dependencies:
# .npmrc
strict-peer-dependencies=true5. Use overrides for transitive deps:
{
"pnpm": {
"overrides": {
"axios": "1.6.0"
}
}
}yarn Best Practices
1. Use Yarn 3+ (Berry) for modern features:
# Enable Corepack (Node 16.10+)
corepack enable
# Set Yarn version
yarn set version stable2. Use workspaces:
{
"workspaces": {
"packages": [
"packages/*"
]
}
}3. Use `yarn why` to understand dependencies:
yarn why lodash4. Configure resolutions:
{
"resolutions": {
"lodash": "4.17.21"
}
}Bun Best Practices
1. Install Bun:
# macOS/Linux
curl -fsSL https://bun.sh/install | bash
# Windows (via npm)
npm install -g bun2. Initialize and install:
# New project
bun init
# Install dependencies (7× faster than npm)
bun install
# CI/CD (frozen lockfile)
bun install --frozen-lockfile3. Add dependencies:
# Production dependency
bun add express
# Dev dependency
bun add -d typescript
# Exact version
bun add lodash@4.17.214. Use workspaces:
{
"workspaces": ["packages/*", "apps/*"]
}# Run in specific workspace
bun run --filter @myorg/ui build5. Security auditing:
# Currently use npm audit (Bun audit in development)
npm audit6. Override transitive dependencies:
{
"overrides": {
"axios": "1.6.0"
}
}When to use Bun:
- Greenfield projects where speed is critical
- Development environments (fast feedback)
- Scripts and tooling (fast startup)
When to prefer pnpm:
- Enterprise monorepos requiring stable workspace support
- Projects with complex peer dependency requirements
- Maximum ecosystem compatibility needed
---
Python (pip / poetry / conda / uv)
Tool Comparison (January 2026)
| Tool | Use Case | Lockfile | Virtual Env | Speed |
|---|---|---|---|---|
| uv (Astral) | All Python projects | uv.lock | Automatic | 10-100× faster |
| pip + venv | Simple projects | requirements.txt (pinned) | Manual (venv) | Baseline |
| pip-tools | Production apps | requirements.txt (pinned) | Manual (venv) | Baseline |
| poetry | Modern Python apps | poetry.lock | Automatic | Moderate |
| conda | Data science, ML | environment.yml | Automatic | Slow |
Recommendations (January 2026):
- New projects: uv (10-100× faster than pip, replaces pip/poetry/virtualenv in single tool)
- Mature projects: Poetry (battle-tested, excellent dependency resolution)
- Simple scripts: pip + venv (minimal setup)
- Data science/ML: conda (binary packages) or uv (faster environment setup)
pip + pip-tools Best Practices
1. Separate `requirements.in` (loose) from `requirements.txt` (pinned):
# requirements.in (loose constraints)
flask>=2.0.0
requests>=2.28.0# Generate pinned requirements.txt
pip-compile requirements.inOutput (`requirements.txt`):
# This file is autogenerated by pip-compile
flask==2.3.2
via -r requirements.in
requests==2.31.0
via -r requirements.in
click==8.1.3
via flask
...2. Separate dev and production requirements:
# requirements-dev.in
-r requirements.txt
pytest>=7.0.0
black>=23.0.03. Use virtual environments:
# Create venv
python3 -m venv venv
# Activate
source venv/bin/activate # Unix
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt4. Use constraints for transitive deps:
# constraints.txt
urllib3==1.26.18 # Pin transitive dependencypip install -c constraints.txt -r requirements.txtPoetry Best Practices
1. Initialize project:
poetry new myproject
cd myproject2. Add dependencies:
# Production dependency
poetry add requests
# Dev dependency
poetry add --group dev pytest
# Install all dependencies
poetry install3. Use dependency groups:
[tool.poetry.group.dev.dependencies]
pytest = "^7.0.0"
black = "^23.0.0"
[tool.poetry.group.test.dependencies]
coverage = "^7.0.0"4. Lock without installing:
poetry lock --no-update5. Export to requirements.txt:
poetry export -f requirements.txt --output requirements.txt --without-hashes6. Configure poetry:
# Use in-project virtualenv
poetry config virtualenvs.in-project true
# Don't create virtualenv (use system Python)
poetry config virtualenvs.create falseconda Best Practices
1. Create environment from file:
# environment.yml
name: myproject
channels:
- conda-forge
- defaults
dependencies:
- python=3.10
- numpy=1.24.0
- pandas=2.0.0
- scikit-learn=1.2.0
- pip:
- custom-package==1.0.0conda env create -f environment.yml
conda activate myproject2. Export environment:
# Export exact environment
conda env export > environment.yml
# Export cross-platform
conda env export --from-history > environment.yml3. Update environment:
conda env update -f environment.yml --prune4. Use conda-lock for reproducibility:
# Install conda-lock
conda install -c conda-forge conda-lock
# Generate lockfile
conda-lock -f environment.yml -p linux-64uv Best Practices (NEW - January 2026)
uv by Astral is an ultra-fast Python package manager written in Rust. It replaces pip, pip-tools, pipx, poetry, pyenv, twine, and virtualenv in a single tool.
1. Install uv:
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Via pip (if needed)
pip install uv2. Initialize project:
# Create new project
uv init myproject
cd myproject
# Creates pyproject.toml and uv.lock3. Add dependencies:
# Add production dependency
uv add requests
# Add dev dependency
uv add --dev pytest
# Add with version constraint
uv add "flask>=2.0"
# Install all dependencies
uv sync4. Run scripts and tools:
# Run Python script
uv run python script.py
# Run tool (like pipx)
uv tool run ruff check .
# Install tool globally
uv tool install ruff5. Manage Python versions:
# Install Python version
uv python install 3.12
# List available versions
uv python list
# Pin version for project
uv python pin 3.126. CI/CD usage:
# Install from lockfile (fast, reproducible)
uv sync --frozen
# Export to requirements.txt (for compatibility)
uv export > requirements.txt7. Workspaces (monorepo):
# pyproject.toml
[tool.uv.workspace]
members = ["packages/*"]Migration from Poetry:
# uv can read pyproject.toml from Poetry
# Just run:
uv sync
# This creates uv.lock from existing pyproject.tomlWhen to use uv:
- All new Python projects (10-100× faster)
- Existing projects wanting faster installs
- Teams standardizing on single tool
- CI/CD pipelines (massive time savings)
When Poetry may still be preferred:
- Complex plugin ecosystem requirements
- Teams with heavy Poetry investment
- Projects requiring Poetry-specific features
---
Rust (Cargo)
Best Practices
1. Commit `Cargo.lock` for applications (not libraries):
Applications:
git add Cargo.lock # GOOD: Commit for reproducibilityLibraries:
echo "Cargo.lock" >> .gitignore # BAD: Don't commit (users generate their own)2. Use `cargo update` to update dependencies:
# Update all dependencies
cargo update
# Update specific package
cargo update -p serde
# Preview updates without applying
cargo update --dry-run3. Use `cargo audit` for security scanning:
# Install cargo-audit
cargo install cargo-audit
# Run audit
cargo audit
# Fix vulnerabilities automatically
cargo audit fix4. Leverage Cargo features for optional dependencies:
[features]
default = ["serde"]
full = ["serde", "tokio", "async"]
[dependencies]
serde = { version = "1.0", optional = true }
tokio = { version = "1.0", optional = true }Usage:
# Build with default features
cargo build
# Build with all features
cargo build --all-features
# Build with specific feature
cargo build --features full5. Use workspaces for multi-crate projects:
# Cargo.toml (workspace root)
[workspace]
members = [
"crates/core",
"crates/api",
"crates/cli"
]
[workspace.dependencies]
serde = "1.0" # Shared version6. Use `cargo-outdated` to check for updates:
cargo install cargo-outdated
cargo outdated---
Go (go mod)
Best Practices
1. Use Go modules (standard since 1.11):
# Initialize module
go mod init github.com/username/project
# Add dependency (automatic)
go get github.com/pkg/errors
# Download dependencies
go mod download2. Commit `go.sum` for reproducibility:
git add go.mod go.sum3. Use `go mod tidy` to clean up:
# Remove unused dependencies
go mod tidy
# Run before commits4. Vendor dependencies for enterprise projects:
# Create vendor directory
go mod vendor
# Build using vendored deps
go build -mod=vendor5. Use semantic import versioning for major versions:
// Import v2+
import "github.com/pkg/errors/v2"# go.mod
require (
github.com/pkg/errors/v2 v2.1.0
)6. Use `go list` to inspect dependencies:
# List all dependencies
go list -m all
# List outdated dependencies
go list -u -m all
# View dependency graph
go mod graph---
Java (Maven / Gradle)
Maven Best Practices
1. Use dependency management section:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>2. Use properties for versions:
<properties>
<spring.version>6.0.0</spring.version>
<jackson.version>2.15.0</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>3. Use `mvn dependency:tree` to view dependencies:
mvn dependency:tree
mvn dependency:tree -Dverbose4. Check for updates:
mvn versions:display-dependency-updatesGradle Best Practices
1. Use version catalogs (Gradle 7.0+):
# gradle/libs.versions.toml
[versions]
spring = "6.0.0"
jackson = "2.15.0"
[libraries]
spring-core = { module = "org.springframework:spring-core", version.ref = "spring" }
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }// build.gradle
dependencies {
implementation libs.spring.core
implementation libs.jackson.databind
}2. Use dependency constraints:
dependencies {
constraints {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
}3. View dependency tree:
./gradlew dependencies
./gradlew dependencies --configuration runtimeClasspath---
PHP (Composer)
Best Practices
1. Commit `composer.lock`:
git add composer.lock2. Use `composer install` (not `composer update`) in production:
# Production
composer install --no-dev --optimize-autoloader
# Development
composer install3. Use version constraints:
{
"require": {
"symfony/http-foundation": "^6.0",
"guzzlehttp/guzzle": "~7.4"
}
}4. Check for security vulnerabilities:
composer audit5. View dependency tree:
composer show --tree---
.NET (NuGet)
Best Practices
1. Use Central Package Management:
<!-- Directory.Packages.props -->
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>2. Use `packages.lock.json`:
dotnet restore --use-lock-file3. Check for updates:
dotnet list package --outdated4. Audit for vulnerabilities:
dotnet list package --vulnerable---
Summary Table (January 2026)
| Ecosystem | Package Manager | Lockfile | Best Tool | Security Audit |
|---|---|---|---|---|
| Node.js | npm/yarn/pnpm/Bun | pnpm-lock.yaml / bun.lock | pnpm or Bun | npm audit |
| Python | pip/poetry/conda/uv | uv.lock / poetry.lock | uv | pip-audit |
| Rust | cargo | Cargo.lock | cargo | cargo audit |
| Go | go mod | go.sum | go mod | govulncheck |
| Java | maven/gradle | n/a / lockfile (Gradle 6.8+) | gradle | mvn dependency-check |
| PHP | composer | composer.lock | composer | composer audit |
| .NET | nuget | packages.lock.json | dotnet | dotnet list package --vulnerable |
---
Quick Decision Guide (January 2026)
Choose package manager based on:
| Scenario | Recommendation |
|---|---|
| New Node.js project | pnpm (stable, fast) or Bun (fastest) |
| Enterprise Node.js monorepo | pnpm (best workspace support) |
| Speed-focused JS development | Bun (7× faster than npm) |
| Existing npm project | Stay with npm or migrate to pnpm |
| New Python project | uv (10-100× faster than pip) |
| Python application (mature) | Poetry or uv |
| Simple Python scripts | pip + venv or uv |
| Data science / ML | conda or uv |
| Rust project | cargo (default) |
| Go project | go mod (default) |
| Java enterprise | maven or gradle |
| PHP project | composer |
| .NET project | nuget |
---
Ecosystem-Specific Anti-Patterns
Node.js
- [FAIL] Using
npm installin CI (usenpm ci) - [FAIL] Not committing lockfiles
- [FAIL] Using
--forceor--legacy-peer-depswithout understanding why - [FAIL] Mixing package managers (npm + yarn in same project)
Python
- [FAIL] Not using virtual environments
- [FAIL] Using
sudo pip install(system-wide installs) - [FAIL] Not pinning versions in
requirements.txt - [FAIL] Mixing conda and pip aggressively
Rust
- [FAIL] Committing
Cargo.lockfor libraries (only for binaries) - [FAIL] Not using
cargo auditfor security - [FAIL] Ignoring
cargo clippywarnings
Go
- [FAIL] Not committing
go.sum - [FAIL] Using
go getto install tools (usego install) - [FAIL] Not running
go mod tidyregularly
---
Remember: Each ecosystem has its own conventions and best practices. Follow the ecosystem's standards for the smoothest experience.