Safeguard
Supply Chain•

What is a purl? The Package URL identifier explained

A purl is a standard URL-style identifier for a software package across ecosystems. See its parts, a worked example and why SBOM tools rely on it.

Safeguard Security Team
3 min read

A purl, short for Package URL, is a standardized, URL-style identifier for a software package that works across ecosystems and distribution channels. It gives tools one consistent way to say "this exact package," whether it comes from npm, Maven, PyPI or elsewhere.

The structure

The purl specification gives the shape as scheme, type, namespace, name, version, qualifiers and subpath:

scheme:type/namespace/name@version?qualifiers#subpath

  • scheme is always pkg
  • type is the package manager or ecosystem, such as npm, maven or pypi (required)
  • namespace is an optional prefix, such as a Maven group ID or a GitHub owner, and its meaning depends on the type
  • name is the package name (required)
  • version is optional
  • qualifiers are optional type-specific key and value pairs, such as architecture or repository
  • subpath is an optional path inside the package

A worked example

The specification's example is pkg:npm/%40angular/animation@12.3.1. It identifies version 12.3.1 of the npm package animation in the @angular namespace. The %40 is an encoded @ character.

Reading a purl left to right tells you the ecosystem first, which matters because the same name can exist in more than one registry and mean different things.

Why SBOM and scanning tools care

Matching a component to a vulnerability record is harder than it sounds. Names differ between ecosystems, and free-text names invite mistakes. A purl removes ambiguity, so an SBOM entry, a vulnerability feed and a license database can all point at the same thing.

Formats like CycloneDX and SPDX can carry a purl on each component. Check that your tools actually fill it in.

Tips for using them

  1. Include the version. A purl without one identifies a package, not a release, and vulnerabilities are tied to releases.
  2. Keep the ecosystem type accurate. A wrong type produces false matches or missed ones.
  3. Encode special characters, as the example does for @.
  4. Compare purls as whole strings after normalizing, instead of hand parsing them with regular expressions.

Safeguard's dependency scanning identifies components by ecosystem and version. A free scan is at gold.safeguard.sh/scan.

Quick check

Is a purl a download link?

No. It looks like a URL but identifies a package. It does not say where to fetch it, though a repository qualifier can hint at that.

Which parts of a purl are required?

The type and the name. The scheme is always pkg, and the rest is optional.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.