# Bom Slimmer

> Reviews a codebase's direct dependencies and designs lightweight, low-risk, zero-dependency custom replacements using cdxgen SBOM evidence, occurrence/callstack usage data, and license and supply-chain risk evaluation. Use when asked to shrink node_modules, reduce dependency bloat or copyleft exposure, or replace utility packages with native or built-in implementations.

- Skill: `cdxgen/bom-slimmer` (Agent Skill)
- Install (CLI): `npx skillmds@latest add cdxgen/bom-slimmer`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cdxgen/bom-slimmer/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cdxgen (https://skillmd.com/u/cdxgen)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cdxgen/bom-slimmer

---


# Skill: BOM Slimmer

This skill guides a local LLM through analyzing a project's direct dependencies, identifying high-overhead packages, and designing low-risk, zero-dependency custom replacements.

---

## 1. Using cdxgen SBOM as the Authoritative Data Source

A CycloneDX SBOM generated by `cdxgen` (`bom.json`) provides a complete, normalized, and machine-readable inventory of all direct and transitive dependencies. Use it as your primary source of truth:

1. **Locate Direct Dependencies**:
   Look under `bom.metadata.component` (the parent package) and trace its relationships in the `dependencies` array.
2. **Trace Dependency Trees**:
   Find the `dependencies` block at the root of the SBOM. Each entry maps a package `ref` to its direct dependency `dependsOn` refs:
   ```json
   {
     "ref": "pkg:npm/foo@1.0.0",
     "dependsOn": ["pkg:npm/bar@2.0.0", "pkg:npm/baz@1.5.0"]
   }
   ```
3. **Calculate Transitive Footprint**:
   For any candidate direct dependency, traverse the `dependsOn` graph in the SBOM to identify how many total sub-packages will be completely purged from `node_modules` if that direct dependency is removed.
4. **Inspect Metadata**:
   Filter out `type: "development"` components or dev-only scopes if you are optimizing production boot time and install footprint.

---

## 2. Advanced Analysis Data Points

### Note 1: Utilizing Occurrence and Callstack Evidence

When `cdxgen` is run under `--profile research` (or during deep Evinse executions), it populates components with schema-valid **occurrences** and **callstacks** under `evidence`:

- **Occurrences**: Check `component.evidence.occurrences` to find exactly which source files and line numbers import or reference the dependency.
- **Callstack**: Check `component.evidence.callstack` to view the execution flows, depth of call paths, and entry points leading to the package.
- **LLM Action**: Parse these arrays to immediately determine the _depth and scope_ of usage without needing manual grep passes. If a package has only a single occurrence at a shallow depth, it is a prime candidate for pruning.

### Note 2: Incorporating License, Author, and Publisher Data

Use the following additional SBOM metadata to guide the business and legal aspects of the replacement:

- **Licenses**: Check the `licenses` array of the component. Replacing copyleft-licensed dependencies (e.g. GPL, LGPL) with a permissive custom implementation is a major compliance win.
- **Authors and Publishers**: Check `authors` and `publisher` fields. Dependencies maintained by single authors or unknown publishers present higher supply chain risk (e.g., maintainer abandonment, malicious takeover) compared to standard built-ins or custom code.

---

## 3. Step-by-Step Analysis Workflow

### Step 1: Mapping the Surface Area

- Read the project's manifest (e.g. `package.json`, `Cargo.toml`, `pyproject.toml`) and gather the list of direct production dependencies.
- Cross-reference this list with `bom.json` to verify their version and active presence in the dependency graph.

### Step 2: Code Search & Usage Audit

- Use occurrences/callstack evidence (if present in the SBOM) or `grep` to scan the codebase for all references.
- Note:
  - Which files import the package.
  - Which specific functions/methods are called.
  - If the usage is isolated to a single file, utility, or helper function.

### Step 3: Assessing Replacement Viability

Evaluate candidates against these key replacement archetypes:

- **Native Replacements**: The functionality is now natively supported by modern runtimes (e.g. replacing `uuid` with `crypto.randomUUID()`, `got`/`axios` with standard `fetch`, or `yoctocolors`/`picocolors` with standard ANSI sequences).
- **High-Overhead/Low-Usage Utilities**: Packages imported to perform trivial tasks (e.g. `properties-reader` to get a single version string, or `keyv` to wrap a standard `Map`).
- **Complex/Risky Packages**: Monolithic parser libraries (like TOML, YAML, HTML parsers, or JSON schema validators). These are **High Risk** to replace because custom parsers frequently miss edge cases or suffer from performance bugs.

### Step 4: Drafting Custom Replacements

For viable candidates, design a zero-dependency JS/TS snippet. Follow these requirements:

1. **Compatibility**: Ensure the new implementation supports the exact same input/output formats and signatures as the replaced library APIs.
2. **Standards**: Avoid complex regexes that could cause backtracking vulnerabilities (e.g. ReDoS). Prefer simple string splitting, slice operations, and standard built-ins.
3. **Cross-Platform**: Support Node.js, Bun, and Deno by using global/web-standard APIs (`globalThis`) where possible.

---

## 4. Risk Assessment Guide

Assign a risk category to each proposed replacement:

| Risk Category   | Criteria                                                                                                                  | Example                                                                       |
| :-------------- | :------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------- |
| **Low Risk**    | Standard built-in exists; utility does basic string formatting/math; isolated to a single non-critical utility.           | Replacing `uuid` with `crypto.randomUUID()` or `yoctocolors` with ANSI codes. |
| **Medium Risk** | Requires writing custom parsing logic for standard formats; used in core execution paths; handles external network calls. | Replacing `cheerio` with regex/slicing for HTML page scraping.                |
| **High Risk**   | Parser/validation logic for complex, specification-heavy formats; deeply integrated across numerous modules.              | Replacing `yaml`, `@babel/parser`, or `ajv` schema validator.                 |

