# Dependency Hygiene

> Keep heavy, pin-pulling adapters out of a project's universal lockfile by declaring them as opt-in extras installed only where needed. Use when adding a dependency with heavy or conflicting transitive pins (LLM libs, PDF/OCR libs, ML frameworks), when a shared environment must stay coherent for training/inference, or when an adapter is only needed by one workspace.

- Skill: `jcdavis131/dependency-hygiene` (Agent Skill)
- Install (CLI): `npx skillmds@latest add jcdavis131/dependency-hygiene`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jcdavis131/dependency-hygiene/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: jcdavis131 (https://skillmd.com/u/jcdavis131)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/jcdavis131/dependency-hygiene

---


# Dependency Hygiene

A single heavy dependency can hold a whole monorepo's environment hostage via its transitive pins. The fix is structural, not behavioral: keep heavy adapters out of the universal lock.

## The rule

If a dependency meets **any** of these, it belongs in an opt-in extra, not the core deps:
- Heavy install (large wheels, model downloads, system libs).
- Transitive pins that constrain foundational libs (tokenizers, transformers, torch, numpy, pillow).
- Only one workspace / one code path actually needs it.
- It pulls a pin that conflicts with the training or inference environment.

Common offenders: `litellm`, `instructor`, `crawl4ai`, `marker-pdf`, `outlines`, `transformers`, `torch`, `sentence-transformers`.

## Pattern (PEP 621 / pyproject)

```toml
[project]
name = "my-package"
dependencies = ["pypdf>=4.0"]          # always needed, light, no conflicting pins

[project.optional-dependencies]
llm = ["litellm>=1.40", "instructor>=1.3"]   # heavy, pin-pulling → opt-in
pdf = ["pypdf>=4.0"]
vector = ["qdrant-client>=1.9"]
```

Install only where needed:

```bash
uv pip install -e ".[llm]"     # the workspace that talks to LLMs
uv pip install -e "."          # everyone else — stays coherent
```

## Write the "why" into the diff

The next agent (or future-you) will see the extra and be tempted to promote it to core deps "for convenience". Stop that with a comment in the pyproject:

```toml
# Heavy adapters (litellm, instructor) are opt-in via `uv pip install` —
# kept out of the universal lock so their transitive pins
# (litellm->tokenizers) can't constrain the shared training environment.
```

A one-line rationale in the same file as the decision is the cheapest possible guardrail.

## Anti-patterns

- **"Just add it to core deps, it's easier."** — one heavy lib in core deps and now every CI job, every worker, every training run inherits its pins.
- **Extras without a comment.** The next contributor re-inlines them.
- **One giant `extras = "all"`** that re-combines everything — defeats the isolation.
- **Promoting an extra back to core without checking the transitive pin set.** Run `uv tree` or `pip show` first.

