Extension · Package Integrity

Pin software to its exact bytes.

Package Integrity carries a content-addressable digest inside a source-qualified version. Because Semantic Versions restores build precedence, an integrity-bearing build is a real, orderable version — not an inert annotation.

integrity specifier
npm:react@18.2.0+sha512.d0a1e5c3…9f2b

npm:react@18.2.0 is the package you already install. +sha512.… is the only new part, a build-metadata-safe transcoding of the artifact's hash.

Why build metadata

SRI can't live in a version. This can.

Subresource Integrity strings look like sha512-<base64>. They can't sit in a version because Base64 uses +, / and =, none of which are valid build-metadata characters ([0-9A-Za-z-]). Package Integrity defines a lossless, grammar-safe transcoding (canonical hex, or compact Base62) so the digest travels inside the version string itself.

Live

Compute a source-qualified integrity.

Pull a package's published integrity from any npm-compatible registry and transcode it into a Package Integrity specifier, then optionally re-download the artifact and verify the bytes in your browser with the Web Crypto API.

Format

A Package Integrity build is one or more integrity digests appended as build metadata:

<version>+<algorithm>.<digest> ( .<algorithm>.<digest> )*
  • <algorithm>: one of sha256, sha384, sha512. The set is extensible; consumers MUST ignore digests whose algorithm they don't recognise and MUST NOT treat that as a failure by itself.
  • <digest>: the raw hash encoded as lowercase hex (canonical, [0-9a-f]+) or compact Base62 ([0-9A-Za-z]+). Both are valid build identifiers.
  • Algorithm and digest are two dot-separated build identifiers, so the pair tokenises trivially.
  • Multiple digests MAY be present and SHOULD be ordered weakest-to-strongest.

Canonical hex lengths: sha256 → 64, sha384 → 96, sha512 → 128 characters.

Precedence

Package Integrity relies on Semantic Versions precedence: build identifiers are compared, so a digest-bearing version is ordered and distinguishable rather than collapsed away. Integrity is advisory to precedence but authoritative to trust: the digest doesn't change what a version means, but a mismatch MUST cause the artifact to be rejected.

Verification

  1. Resolve name@version from the named source (npm: → the registry).
  2. Obtain the artifact (for npm, the version's tarball).
  3. Compute the digest of the artifact bytes with <algorithm>.
  4. Transcode and compare to <digest>. It satisfies the identity iff every listed algorithm the consumer supports matches, and at least one supported algorithm was present.
  5. A mismatch MUST be a fatal integrity error.

The transcoding is lossless: npm's sha512-<base64> is the same bytes as sha512.<hex> here.

vs. Dependency Locks

Dependency Locks capture integrity for an entire resolved subgraph in a digest table. Package Integrity is the single-artifact, inline form for one identity. They compose: a lock pins the graph; an inline digest pins one package where a full lock is unnecessary. A digest also composes with a Build Variant: 1.0.0+linux.x64.musl.sha512.… pins the exact bytes of one target.

Grammar (BNF)

Building on VERSION.bnf's <build>:

<integrity build> ::= <integrity> ( "." <integrity> )*
<integrity>       ::= <algorithm> "." <digest>
<algorithm>       ::= "sha256" | "sha384" | "sha512"
<digest>          ::= <hex digest> | <base62 digest>
<hex digest>      ::= <hex> <hex>+
<base62 digest>   ::= <base62 char> <base62 char>+
<hex>             ::= "0" … "9" | "a" … "f"
<base62 char>     ::= "0" … "9" | "A" … "Z" | "a" … "z"