> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scanoss.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dependencies

> How the Dependencies page shows how each package reached a project: coverage per manifest, the Packages and Tree views, why a package is there, and how Earnie resolves dependencies from lockfiles and build tools.

A project's **Dependencies** page shows how each package reaches your project: which manifest declares it, and which packages pull it in. Use it when a finding names a package you never chose. The page shows the chain of packages that brought it in, so you know which direct dependency to upgrade.

To open it, select a project, then **Dependencies** in the sidebar. It sits between **Models** and **SBOMs**. Every role that can read the project can open it.

The page opens on the same scan as **Review**: the project's newest completed full scan. Use the scan picker at the top right to look at another completed scan. The link keeps your choice. Earnie keeps the dependency graphs of only the newest three scans of each project, so an older scan can lose its graph. A scan that recorded no graph says so and keeps the picker.

## Coverage

Above the views, **Coverage** lists every manifest the scan collected, how far each one resolved, and where the information came from. Read it before you trust an absence: a package missing under a manifest that isn't complete may simply not have been found.

| Completeness | What it means |
| - | - |
| **Complete** | Earnie resolved every dependency under the manifest. A package that isn't shown there isn't a dependency. |
| **Partial** | Earnie resolved some dependencies and not the rest. The reason says why, for example that the package registry or mirror couldn't be reached. |
| **Unknown** | Earnie could resolve nothing beyond the packages the manifest declares. The reason says why. |

Each manifest also says what produced its information: a lockfile, a build toolchain, the manifest alone, or an imported SBOM. A Go module's `go.sum` is a list of checksums, so it isn't listed. Its `go.mod` is.

## Packages

**Packages** is the view the page opens on. It lists every package of the scan once, however many manifests and paths hold it. Each row shows:

* **Relation**: **Direct**, or **Transitive** with its depth.
* **Comes in through**: the direct dependency that brings it in.
* **Required by**: how many packages need it.
* Its open findings, and its manifest.

Packages behind open findings come first, worst vulnerability first. The rest follow, direct before transitive. Transitive packages carry findings like direct ones: each one gets its vulnerabilities and license, and the project's policies evaluate them, so a policy that blocks a vulnerability blocks it whether a manifest declares the package or another package brings it in. That data can arrive a few seconds after the scan completes, and the scan's gate is decided again when it does. The findings badge describes that version only: when a project holds two versions of a package, the vulnerable one carries the badge, and a fixed one beside it carries none.

To narrow the list:

* **All**, **Direct**, and **Transitive** filter by relation.
* **With open findings** keeps only the packages that still need a decision.
* **Hide dev-only** leaves out the packages your project reaches only through tests and build tooling.
* **Search packages** matches part of a name or a package URL.

### Why a Package Is Here

Select a package to open a panel beside the list:

* **Why it is here** says whether a manifest declares the package, or which direct dependencies bring it in. Upgrading or removing one of those is how you change it.
* **Paths** lists the five shortest chains from a manifest to the package.
* **Findings** links to the package in **Review**.
* **Show in tree** opens the **Tree** at the package.

A package that arrives along three or more paths also offers **Show paths as graph**. The graph holds every path to the package and nothing else. It reads left to right: the manifest, the direct dependency you can change, what sits between, and the package. Select a box to keep only the paths through it.

## Tree

**Tree** lists each manifest, the packages it declares, and what those pull in, as rows you can fold. A package appears in full once under each manifest. A later appearance says **Expanded above**.

* **It starts shallow.** The first view holds each manifest and the packages it declares directly, so a large project opens quickly. A package whose dependencies aren't shown yet carries a button such as **3 dependencies**. Select it to show them.
* **Search shows paths.** Type part of a name or a package URL in **Search packages**. Earnie adds only the packages on the way to each match, and marks the matches with **Match**. Clear the box to go back to the shallow view.
* **Follow the findings.** **Expand paths to findings** opens the paths to the packages behind open findings. **Collapse all** goes back to the first view.
* **Large trees show a window.** When a project has more packages than the tree can hold, a notice says how many of the total you're seeing. Narrow the tree with search rather than expanding everything.

The address of the page holds the view, the filters, the search, and the selected package, so you can paste a link to a package.

## How Earnie Resolves Dependencies

Earnie reads the dependency tree from three places.

**Lockfiles.** Earnie reads the lockfiles in your scan and adds the packages they pin, including the ones no manifest names. It reads `package-lock.json`, `npm-shrinkwrap.json`, `yarn.lock`, `pnpm-lock.yaml`, `Cargo.lock`, `Gemfile.lock`, `poetry.lock`, `uv.lock`, `Pipfile.lock`, `composer.lock`, `packages.lock.json`, `gradle.lockfile`, and `go.mod`. A `go.mod`, a `gradle.lockfile`, and a `Pipfile.lock` pin versions without saying which package depends on which. Their packages are listed, and their lockfile counts as incomplete.

**Toolchain resolution.** A Go `go.mod` or a Maven `pom.xml` that no complete lockfile covers is resolved by the package manager itself. Earnie runs it in an isolated container with no access to your other data. A Maven project has no lockfile, so without the toolchain it stays declaration-only. The scan finishes and publishes its findings first. The resolved packages then join the graph, so the page can fill in a moment after the scan reads **Completed**. A manifest that the toolchain resolved shows the source **Toolchain**.

Until the toolchain resolves a Go module that `go.mod` marks `// indirect`, Earnie lists it as **Unattributed**, with no known path. Once resolved, it's **Transitive** under the module that imports it.

**Imported SBOMs.** When a scan imports an SBOM, Earnie records the dependency edges the SBOM states.

### When the Toolchain Can't Resolve

When the toolchain can't resolve a manifest, the manifest keeps what the scan already knew, and its reason says why. None of these reasons fails or delays a scan.

| Reason | What to do |
| - | - |
| The dependency sandbox is not set up on this deployment | Ask an administrator to enable it. On a self-hosted installation, no resolver runs, so only what the manifest and lockfile name is shown. |
| The package registry or mirror could not be reached | On a self-hosted installation, an administrator points the resolver at a mirror with `SCANS_SANDBOX_GOPROXY` for Go and `SCANS_SANDBOX_MIRROR_CIDRS` for the network of a private registry. |
| The resolution run failed before it finished | Scan again to retry. The findings the scan published aren't affected. If it keeps failing, ask an administrator to check the logs of the dependency worker. |
| The package manager is not installed in the resolver image | An administrator runs an image that ships it. |
| The package manager exited with an error | Check that the manifest builds on its own and that its private packages are reachable. Earnie doesn't show the tool's message on this page. |
| The package manager ran out of time | An administrator can raise `SANDBOX_RESOLVE_EXEC_TIMEOUT` in `tenant.env`. |
| The lockfile records no dependency edges | The packages are listed without the paths between them. Only the toolchain resolves the full tree. If this deployment has none, ask an administrator to enable it. |

A manifest that isn't **Complete** never closes findings for packages it no longer lists, so an unresolved tree never makes a dependency look removed.

## Dev Dependencies

A dependency your project needs only to develop it, such as a test runner or a linter, is marked as a dev dependency. Earnie knows this only where the manifest and its lockfile say so. The packages a dev dependency pulls in are dev too, unless a runtime dependency also reaches them. The graph marks them, and **Hide dev-only** on the **Packages** view leaves them out.

SBOM exports leave dev dependencies out by default. The **Include dev dependencies** switch brings them back. See [Exporting SBOMs](https://docs.scanoss.com/en/latest/earnie/evidence/exporting-sboms.md).

## From a Package to a Decision

The same graph feeds three other places.

* **Introduced via in Review.** For a dependency, **Introduced via** sits below **Declared** in a component's panel. It shows the shortest paths, at most five, each as a breadcrumb from the manifest to the package, for example `package.json > express > body-parser > qs`. For a transitive dependency, it leads with the fix: **Upgrade express (direct dependency)**, one line for each direct dependency the package arrives through. **View in graph** opens this page on the package. See [Triaging findings](https://docs.scanoss.com/en/latest/earnie/using-earnie/triaging-findings.md).
* **Deciding a subtree.** Next to the paths, **Decide packages introduced via** followed by the package's name decides, in one step, every dependency below it in the graph. It's offered to the roles that can record decisions.
* **Policies.** A policy can read how a dependency arrived. `finding.dependency.relation` is `direct`, `transitive`, `unattributed`, or `unknown`, and `finding.dependency.depth` is the length of the shortest path from a manifest. `unknown` means no graph holds the package, so treat it as missing evidence, not as direct. A rule on depth checks `has(finding.dependency.depth)` first. See [Setting policies](https://docs.scanoss.com/en/latest/earnie/using-earnie/setting-policies.md).

## What's Next

To decide a finding on a package you found here, go to [Triaging findings](https://docs.scanoss.com/en/latest/earnie/using-earnie/triaging-findings.md). To change which files a scan reads, see [Scan configuration](https://docs.scanoss.com/en/latest/earnie/using-earnie/scan-configuration.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.