home / skills / aj-geddes / useful-ai-prompts / dependency-management

dependency-management skill

/skills/dependency-management

This skill helps you manage dependencies across ecosystems, resolve conflicts, audit security, and maintain reproducible builds with best practices.

npx playbooks add skill aj-geddes/useful-ai-prompts --skill dependency-management

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
10.4 KB
---
name: dependency-management
description: Manage project dependencies across languages including npm install, package versioning, dependency conflicts, security scanning, and lock files. Use when dealing with dependencies, version pinning, semantic versioning, or resolving conflicts.
---

# Dependency Management

## Overview

Comprehensive dependency management across JavaScript/Node.js, Python, Ruby, Java, and other ecosystems. Covers version control, conflict resolution, security auditing, and best practices for maintaining healthy dependencies.

## When to Use

- Installing or updating project dependencies
- Resolving version conflicts
- Auditing security vulnerabilities
- Managing lock files (package-lock.json, Gemfile.lock, etc.)
- Implementing semantic versioning
- Setting up monorepo dependencies
- Optimizing dependency trees
- Managing peer dependencies

## Instructions

### 1. **Package Manager Basics**

#### Node.js / npm/yarn/pnpm
```bash
# Initialize project
npm init -y

# Install dependencies
npm install express
npm install --save-dev jest
npm install --save-exact lodash  # Exact version

# Update dependencies
npm update
npm outdated  # Check for outdated packages

# Audit security
npm audit
npm audit fix

# Clean install from lock file
npm ci  # Use in CI/CD

# View dependency tree
npm list
npm list --depth=0  # Top-level only
```

#### Python / pip/poetry
```bash
# Using pip
pip install requests
pip install -r requirements.txt
pip freeze > requirements.txt

# Using poetry (recommended)
poetry init
poetry add requests
poetry add --dev pytest
poetry add "django>=3.2,<4.0"
poetry update
poetry show --tree
poetry check  # Verify lock file
```

#### Ruby / Bundler
```bash
# Initialize
bundle init

# Install
bundle install
bundle update gem_name

# Audit
bundle audit check --update

# View dependencies
bundle list
bundle viz  # Generate dependency graph
```

### 2. **Semantic Versioning (SemVer)**

**Format:** MAJOR.MINOR.PATCH (e.g., 2.4.1)

```json
// package.json version ranges
{
  "dependencies": {
    "exact": "1.2.3",           // Exactly 1.2.3
    "patch": "~1.2.3",          // >=1.2.3 <1.3.0
    "minor": "^1.2.3",          // >=1.2.3 <2.0.0
    "major": "*",               // Any version (avoid!)
    "range": ">=1.2.3 <2.0.0",  // Explicit range
    "latest": "latest"          // Always latest (dangerous!)
  }
}
```

**Best Practices:**
- `^` for libraries: allows backward-compatible updates
- `~` for applications: more conservative, patch updates only
- Exact versions for critical dependencies
- Lock files for reproducible builds

### 3. **Dependency Lock Files**

#### package-lock.json (npm)
```json
{
  "name": "my-app",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "node_modules/express": {
      "version": "4.18.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
      "integrity": "sha512-...",
      "dependencies": {
        "body-parser": "1.20.1"
      }
    }
  }
}
```

**Lock File Rules:**
- ✅ Always commit lock files to version control
- ✅ Use `npm ci` in CI/CD (faster, more reliable)
- ✅ Regenerate if corrupted: delete and run `npm install`
- ❌ Never manually edit lock files
- ❌ Don't mix package managers (npm + yarn)

#### poetry.lock (Python)
```toml
[[package]]
name = "requests"
version = "2.28.1"
description = "HTTP library"
category = "main"
optional = false
python-versions = ">=3.7"

[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<3"
```

### 4. **Resolving Dependency Conflicts**

#### Scenario: Version Conflict
```bash
# Problem: Two packages require different versions
# package-a requires lodash@^4.17.0
# package-b requires lodash@^3.10.0

# Solution 1: Check if newer versions are compatible
npm update lodash

# Solution 2: Use resolutions (yarn/package.json)
{
  "resolutions": {
    "lodash": "^4.17.21"
  }
}

# Solution 3: Use overrides (npm 8.3+)
{
  "overrides": {
    "lodash": "^4.17.21"
  }
}

# Solution 4: Fork and patch
npm install patch-package
npx patch-package some-package
```

#### Python Conflict Resolution
```bash
# Find conflicts
pip check

# Using pip-tools for constraint resolution
pip install pip-tools
pip-compile requirements.in  # Generates locked requirements.txt

# Poetry automatically resolves conflicts
poetry add package-a package-b  # Will find compatible versions
```

### 5. **Security Vulnerability Management**

#### npm Security Audit
```bash
# Audit current dependencies
npm audit

# Show detailed report
npm audit --json

# Fix automatically (may introduce breaking changes)
npm audit fix

# Fix only non-breaking changes
npm audit fix --production --audit-level=moderate

# Audit in CI/CD
npm audit --audit-level=high  # Fail if high vulnerabilities
```

#### Using Snyk
```bash
# Install Snyk CLI
npm install -g snyk

# Authenticate
snyk auth

# Test for vulnerabilities
snyk test

# Monitor project
snyk monitor

# Fix vulnerabilities interactively
snyk wizard
```

#### Python Security
```bash
# Using safety
pip install safety
safety check
safety check --json

# Using pip-audit (official tool)
pip install pip-audit
pip-audit
```

### 6. **Monorepo Dependency Management**

#### Workspace Structure (npm/yarn/pnpm)
```json
// package.json (root)
{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}
```

```bash
# Install all dependencies
npm install

# Add dependency to specific workspace
npm install lodash --workspace=@myorg/package-a

# Run script in workspace
npm run test --workspace=@myorg/package-a

# Run script in all workspaces
npm run test --workspaces
```

#### Lerna Example
```bash
# Initialize lerna
npx lerna init

# Bootstrap (install + link)
lerna bootstrap

# Add dependency to all packages
lerna add lodash

# Version and publish
lerna version
lerna publish
```

### 7. **Peer Dependencies**

```json
// library package.json
{
  "name": "my-react-library",
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0"
  },
  "peerDependenciesMeta": {
    "react-dom": {
      "optional": true  // Makes peer dependency optional
    }
  }
}
```

**When to Use Peer Dependencies:**
- Plugin architecture (webpack plugins, babel plugins)
- React/Vue component libraries
- Framework extensions
- Prevents multiple versions of same package

### 8. **Performance Optimization**

#### Reduce Bundle Size
```bash
# Analyze bundle size
npm install -g bundle-buddy
npm install --save-dev webpack-bundle-analyzer

# Use production build
npm install --production

# Prune unused dependencies
npm prune

# Find duplicate packages
npm dedupe
npx yarn-deduplicate  # For yarn
```

#### package.json Optimization
```json
{
  "dependencies": {
    // ❌ Don't install entire lodash
    "lodash": "^4.17.21",

    // ✅ Install only what you need
    "lodash.debounce": "^4.0.8",
    "lodash.throttle": "^4.1.1"
  }
}
```

### 9. **CI/CD Best Practices**

```yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      # Cache dependencies
      - uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

      # Use ci command (faster, more reliable)
      - run: npm ci

      # Security audit
      - run: npm audit --audit-level=high

      # Check for outdated dependencies
      - run: npm outdated || true

      - run: npm test
```

### 10. **Dependency Update Strategies**

#### Automated Updates (Dependabot)
```yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10
    groups:
      dev-dependencies:
        dependency-type: "development"
    ignore:
      - dependency-name: "react"
        versions: ["17.x"]
```

#### Manual Update Strategy
```bash
# Step 1: Check outdated
npm outdated

# Step 2: Update dev dependencies first
npm update --save-dev

# Step 3: Test thoroughly
npm test

# Step 4: Update production deps (one by one for major updates)
npm update express

# Step 5: Review changelog
npm view express versions
npm view express@latest
```

## Best Practices

### ✅ DO
- Commit lock files to version control
- Use `npm ci` or equivalent in CI/CD pipelines
- Regular dependency audits (weekly/monthly)
- Keep dependencies up-to-date (automate with Dependabot)
- Use exact versions for critical dependencies
- Document why specific versions are pinned
- Test after updating dependencies
- Use semantic versioning correctly
- Minimize dependency count
- Review dependency licenses

### ❌ DON'T
- Manually edit lock files
- Mix package managers (npm + yarn in same project)
- Use `npm install` in CI/CD (use `npm ci`)
- Ignore security vulnerabilities
- Use wildcards (*) for versions
- Install packages globally when local install is possible
- Commit node_modules to git
- Use `latest` tag in production
- Blindly run `npm audit fix`
- Install unnecessary dependencies

## Common Patterns

### Pattern 1: Strict Version Control
```json
{
  "dependencies": {
    "critical-package": "1.2.3",  // Exact version
    "stable-package": "~2.3.4"    // Patch updates only
  },
  "engines": {
    "node": ">=16.0.0 <19.0.0",
    "npm": ">=8.0.0"
  }
}
```

### Pattern 2: Optional Dependencies
```json
{
  "optionalDependencies": {
    "fsevents": "^2.3.2"  // macOS only, won't break on other OS
  }
}
```

### Pattern 3: Custom Registry
```bash
# .npmrc
registry=https://registry.npmjs.org/
@myorg:registry=https://npm.pkg.github.com/

# Or scoped
npm install --registry=https://custom-registry.com/
```

## Tools & Resources

- **npm**: Default Node.js package manager
- **Yarn**: Fast, reliable, secure dependency management
- **pnpm**: Efficient disk space usage, strict node_modules
- **Poetry**: Modern Python dependency management
- **Bundler**: Ruby dependency management
- **Snyk**: Security vulnerability scanning
- **Dependabot**: Automated dependency updates
- **Renovate**: Advanced dependency update automation
- **npm-check-updates**: Interactive dependency updates

## Quick Reference

```bash
# Check versions
node --version
npm --version

# Clear cache if issues
npm cache clean --force
yarn cache clean
pnpm store prune

# Reinstall all dependencies
rm -rf node_modules package-lock.json
npm install

# Why is this dependency installed?
npm ls package-name
yarn why package-name

# Find security issues
npm audit
snyk test

# Update all dependencies to latest
npx npm-check-updates -u
npm install
```

Overview

This skill helps manage project dependencies across multiple ecosystems (Node.js, Python, Ruby, Java, and monorepos). It focuses on installing and updating packages, resolving version conflicts, maintaining lock files, and running security audits to keep builds reproducible and safe. Use it to implement semantic versioning, automate updates, and optimize dependency trees.

How this skill works

The skill inspects dependency manifests and lock files, runs package manager commands (npm, yarn, pnpm, pip/poetry, bundler), and recommends fixes for conflicts and vulnerabilities. It suggests version ranges, lock-file policies, CI/CD practices, and automation options like Dependabot or Renovate. It also provides concrete commands and patterns for resolving conflicts, auditing security, and optimizing bundle size.

When to use it

  • Installing or updating project dependencies
  • Resolving version conflicts between packages
  • Auditing and fixing security vulnerabilities
  • Setting up or enforcing lock file policies in CI/CD
  • Configuring monorepo or workspace dependency workflows
  • Automating dependency updates and review processes

Best practices

  • Commit lock files and use exact or controlled ranges for critical deps
  • Use ci-style install commands (npm ci / poetry lock + install) in CI/CD
  • Audit dependencies regularly and fail CI on high-severity findings
  • Prefer ^ for libraries, ~ for applications, exact pins for critical packages
  • Avoid mixing package managers and never manually edit lock files
  • Minimize dependency count and prefer focused packages over monolithic libraries

Example use cases

  • Fix a transitive version conflict with overrides/resolutions or patch-package
  • Run a weekly security audit and open PRs for fixes using Dependabot or Renovate
  • Convert a project to use a lock-file-first workflow and enforce npm ci in CI
  • Add a dependency to a single workspace in a monorepo and run tests there
  • Shrink bundle size by replacing heavy packages with targeted modules (e.g., lodash.*)
  • Use poetry or pip-tools to produce pinned requirements.txt for reproducible Python builds

FAQ

Should I commit lock files to version control?

Yes — always commit lock files to ensure reproducible builds and consistent installs across environments.

When is it safe to use automated update bots?

Use bots for routine patch/minor updates with automated tests; require human review for major upgrades and breaking-change candidates.