Skip to main content
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. 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. 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.

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.
  • 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.

What’s Next

To decide a finding on a package you found here, go to Triaging findings. To change which files a scan reads, see Scan configuration.