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

# Supported Ecosystems

> Which package ecosystems ZeroPath analyzes, and what each one needs for full transitive coverage

ZeroPath's SCA analyzers recognize the following ecosystems out of the box:

<Columns cols={3}>
  <Card title="npm / Yarn / pnpm" icon="js" iconType="brands" />

  <Card title="PyPI" icon="python" iconType="brands" />

  <Card title="Go modules" icon="golang" iconType="brands" />

  <Card title="Maven / Gradle / SBT" icon="java" iconType="brands" />

  <Card title="NuGet" icon="https://mintcdn.com/zeropath/3LQWG-DWQmf_zR2q/icons/csharp.svg?fit=max&auto=format&n=3LQWG-DWQmf_zR2q&q=85&s=a369b07fdfa85a098eef35c035d7c098" width="128" height="128" data-path="icons/csharp.svg" />

  <Card title="RubyGems" icon="https://mintcdn.com/zeropath/3LQWG-DWQmf_zR2q/icons/ruby.svg?fit=max&auto=format&n=3LQWG-DWQmf_zR2q&q=85&s=e98ed481966bcbb1508f8d69e680b60e" width="128" height="128" data-path="icons/ruby.svg" />

  <Card title="crates.io (Cargo)" icon="rust" iconType="brands" />

  <Card title="Packagist / Composer" icon="php" iconType="brands" />

  <Card title="Hex (Elixir)" icon="https://mintcdn.com/zeropath/3LQWG-DWQmf_zR2q/icons/elixir.svg?fit=max&auto=format&n=3LQWG-DWQmf_zR2q&q=85&s=1561f8905cfcc6ab231dbcb15aaf5db3" width="128" height="128" data-path="icons/elixir.svg" />

  <Card title="Pub (Dart/Flutter)" icon="https://mintcdn.com/zeropath/3LQWG-DWQmf_zR2q/icons/dart.svg?fit=max&auto=format&n=3LQWG-DWQmf_zR2q&q=85&s=c3fa2a0a3350a59c4f7fcd10cbeff84b" width="128" height="128" data-path="icons/dart.svg" />

  <Card title="Swift" icon="swift" iconType="brands" />

  <Card title="Haskell (Hackage)" icon="code" />

  <Card title="R (CRAN)" icon="code" />
</Columns>

Every dependency record tracks whether ZeroPath saw it declared **directly** or
pulled in **transitively**, so you can apply different policies to first-party
choices and vendor libraries. Development and optional dependencies declared in
your manifests are inventoried too; [reachability](/sca/reachability) helps
separate runtime-relevant findings from dev-only noise.

## How resolution works

ZeroPath resolves your dependency graph directly from your manifests wherever it
can, with no build step or container required, and falls back to your committed
**lockfile** everywhere else. The practical contract is per-ecosystem, summarized
in the table below. Two rules hold everywhere:

* **Direct dependencies are scanned even when the transitive graph can't be
  built.** ZeroPath records and vulnerability-matches the packages you declared
  directly, so a missing lockfile costs you transitive depth, not your direct
  findings.
* **Unknown versions aren't guessed.** If a version can't be determined, for
  example an unresolved range or a broken parent chain, the package is still
  recorded in your inventory and SBOM but is not vulnerability-matched. This
  avoids false positives from guessed versions.

### Coverage without a committed lockfile

| Ecosystem                                                                 | Without a committed lockfile                                                                                                            |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| npm / Yarn / pnpm                                                         | **Full transitive coverage** — resolved directly from `package.json`                                                                    |
| Maven (`pom.xml`)                                                         | **Full transitive coverage** — resolved deterministically from your POMs (parent, BOM, and properties); no lockfile required            |
| Python (`requirements.txt`, fully `==`-pinned)                            | **Resolved as-is** — every pinned package is scanned (a `pip freeze` / `pip-compile` file already lists transitives)                    |
| Python (`pyproject.toml`, `Pipfile`, partially-pinned `requirements.txt`) | **Direct deps only** — manage via `pyproject.toml`/`Pipfile` and commit `poetry.lock`, `uv.lock`, or `Pipfile.lock` (or fully `==`-pin) |
| Go modules                                                                | **Direct deps only** — commit `go.sum` (`go mod tidy`)                                                                                  |
| Gradle (`build.gradle`, `.kts`)                                           | **Direct deps only** — commit `gradle.lockfile`                                                                                         |
| SBT (`build.sbt`)                                                         | **Direct deps only** — commit `build.sbt.lock` or `lock.sbt`                                                                            |
| Cargo (`Cargo.toml`)                                                      | **Direct deps only** — commit `Cargo.lock`                                                                                              |
| NuGet (`*.csproj`, `*.fsproj`, `*.vbproj`)                                | **Direct deps only** — commit `packages.lock.json`                                                                                      |
| Ruby                                                                      | **Direct deps only** — commit `Gemfile.lock`                                                                                            |
| PHP                                                                       | **Direct deps only** — commit `composer.lock`                                                                                           |
| Elixir                                                                    | **Direct deps only** — commit `mix.lock`                                                                                                |
| Dart / Flutter                                                            | **Direct deps only** — commit `pubspec.lock`                                                                                            |
| Swift                                                                     | **Direct deps only** — commit `Package.resolved`                                                                                        |

<Warning>
  For every ecosystem marked **Direct deps only**, a missing lockfile means
  transitive dependencies aren't resolved and range specifiers stay ambiguous, so
  transitive vulnerability matching and SBOM completeness suffer. ZeroPath still
  records your direct dependencies and flags the manifest with a **Transitive
  dependencies unresolved** warning so the gap is visible. See
  [Coverage & warnings](/sca/coverage) for how to clear it, including the
  [commands to generate each lockfile](/sca/coverage#generate-lockfiles-before-scanning).
</Warning>

<Tip>
  For **npm/Yarn/pnpm**, **Maven**, and a fully `==`-pinned **`requirements.txt`**,
  a committed lockfile is optional — it only makes scans faster and more
  deterministic.
</Tip>

## Compiled & vendored artifacts

Binary JVM artifacts committed to your repository, such as JARs and WARs, are
scanned for the packages embedded inside them. Those packages appear in your inventory
alongside source-declared dependencies, with a **Compiled** source-type badge
(e.g. JAR, WAR), so you can see vendored or pre-built libraries that manifest-only
analysis would miss. The Dependencies inventory lets you filter by
**Source Type** to isolate compiled vs. source-declared findings.

## Ecosystem notes

<AccordionGroup>
  <Accordion title="Go modules">
    ZeroPath handles the `+incompatible` suffix used by pre-module Go packages
    (major version 2+), matching versions like `v3.2.0+incompatible` to known
    advisories. Go pseudo-versions (e.g. `v0.0.0-20231215084216-abcdef123456`) are
    commit snapshots, not published releases, so ZeroPath records them in inventory
    but doesn't attempt advisory version-matching on them.
  </Accordion>

  <Accordion title="Maven">
    Multi-module (reactor) builds are fully resolved: ZeroPath indexes every POM
    in the repository and resolves `<parent>` references across modules even when
    `<relativePath/>` is empty or absent, so a child can inherit
    `<dependencyManagement>` versions from a sibling's parent. Parent POMs that
    declare dependencies only in `<dependencyManagement>` are captured, and
    classifier-bearing artifacts are attributed to the correct package. When a
    parent POM can't be resolved locally or remotely, versions inherited through
    that chain are treated as unresolved rather than guessed.
  </Accordion>

  <Accordion title="Gradle">
    Beyond plain `build.gradle(.kts)` declarations, ZeroPath also recognizes
    dependencies declared through version catalogs (`libs.versions.toml`),
    convention plugins, platform/BOM constraints, and the Kotlin DSL. Commit
    `gradle.lockfile` (`./gradlew dependencies --write-locks`) for the full
    transitive tree.
  </Accordion>

  <Accordion title="SBT (Scala)">
    ZeroPath records direct dependencies from `build.sbt`, and parses a committed
    lockfile for the full transitive tree: `build.sbt.lock`
    ([sbt-dependency-lock](https://github.com/stringbean/sbt-dependency-lock)) or
    `lock.sbt` ([sbt-lock](https://github.com/tkawachi/sbt-lock)).
  </Accordion>

  <Accordion title="NuGet">
    Package ids are matched case-insensitively, so casing differences between a
    manifest and the registry never cause a miss. Opt into NuGet lockfile mode and
    commit `packages.lock.json` (`dotnet restore --use-lock-file --force-evaluate`,
    NuGet 4.9+) for transitive coverage.
  </Accordion>

  <Accordion title="Cargo (Rust)">
    Binary crates commit `Cargo.lock` by default, and ZeroPath uses it directly.
    Library crates commonly omit it (per Cargo's guidance); commit
    `Cargo.lock` (`cargo generate-lockfile`) for transitive coverage. A crate that
    resolves to multiple versions in the same graph is reported as separate
    `(name, version)` pairs, so each one reaches advisory matching.
  </Accordion>

  <Accordion title="Python manifest formats">
    All common formats are supported:

    * **requirements.txt** — standard pip format
    * **Pipfile** — Pipenv (`[packages]` / `[dev-packages]`)
    * **pyproject.toml (Poetry)** — including 1.2+ group dependencies
    * **pyproject.toml (PEP 621)** — the `[project]` table used by uv, hatch, flit,
      setuptools, and pdm (both `dependencies` and `optional-dependencies`)
  </Accordion>
</AccordionGroup>

<Info>
  Every finding records a package's place in the graph (direct or transitive) and
  the chain that introduced it, and links back to the exact manifest file and line
  where the dependency was declared rather than the lockfile. A package reached
  through multiple dependency paths is deduplicated into a single inventory entry,
  so counts reflect unique packages. See [Blast radius](/sca/blast-radius) for how
  the dependency chain becomes call-site impact during an upgrade.
</Info>
