npm package: @superxepic/nodewhy
Description: 🔍 Why is this package in your node_modules? nodewhy tells you exactly who dragged it in and how deep.
Author: Suryakant Subudhi
Latest version: 1.0.0

# nodewhy

> 🔍 Why is this package in your `node_modules`?  
> Trace exactly who dragged it in — and how deep.

A CLI tool & Node.js library by **[superxepic](https://superxepic.com)**.

---

## Install

```bash
npm install -g nodewhy
# or use without installing:
npx nodewhy <package>
```

---

## Usage

```bash
nodewhy <package-name> [options]
```

### Examples

```bash
# Who pulled in lodash?
nodewhy lodash

# Check a specific project
nodewhy axios --cwd /path/to/project

# Output as JSON (great for scripts)
nodewhy typescript --json

# Ignore devDependencies from your root
nodewhy eslint --no-dev
```

### Sample Output

```
nodewhy · lodash
────────────────────────────────────────────────

  ◆ Pulled in transitively via 1 path:

    my-app (your project)
    ├── some-lib@2.1.0 [dep]
       └── another-lib@1.0.4 [dep]
          └─▶ lodash@4.17.21 [dep]

  depth: 3 · paths found: 1
```

---

## Options

| Flag              | Description                                 |
| ----------------- | ------------------------------------------- |
| `--json`          | Output result as JSON                       |
| `--all`           | Show all transitive paths (default: max 10) |
| `--cwd <dir>`     | Set project root (default: `process.cwd()`) |
| `--no-dev`        | Exclude `devDependencies` from root package |
| `--help`, `-h`    | Show help                                   |
| `--version`, `-v` | Show version                                |

---

## Dependency Type Legend

| Badge    | Meaning                |
| -------- | ---------------------- |
| `[dep]`  | `dependencies`         |
| `[dev]`  | `devDependencies`      |
| `[peer]` | `peerDependencies`     |
| `[opt]`  | `optionalDependencies` |

---

## Programmatic API

```typescript
import { findWhy, formatResult } from "nodewhy";

const result = await findWhy("lodash", {
  projectRoot: "/path/to/project",
  includeDevDeps: true,
});

console.log(formatResult(result, "my-app"));

// Or access the raw data:
console.log(result.found); // boolean
console.log(result.paths); // TraceStep[][]
```

### `findWhy(packageName, options)`

| Param                    | Type      | Description                                 |
| ------------------------ | --------- | ------------------------------------------- |
| `packageName`            | `string`  | The package to search for                   |
| `options.projectRoot`    | `string`  | Path to the project root                    |
| `options.includeDevDeps` | `boolean` | Include devDeps from root (default: `true`) |

Returns a `TraceResult`:

```typescript
interface TraceResult {
  target: string; // package you searched for
  found: boolean; // whether it exists in node_modules
  paths: TraceStep[][]; // all dependency chains leading to it
}

interface TraceStep {
  package: string;
  version: string;
  dependencyType:
    | "dependencies"
    | "devDependencies"
    | "peerDependencies"
    | "optionalDependencies";
}
```

---

## How it works

`nodewhy` performs a **breadth-first search** through your project's `node_modules`, reading each package's `package.json` to build a dependency graph. It then finds every path from your project root to the target package — including all transitive chains — and presents them ranked by depth.

No `npm ls` subprocess. No internet. Pure filesystem traversal.

---

## License

MIT © [superxepic](https://superxepic.com)