Registries

Packagist

Packagist's package document, one per vendor/name with every version inside, and the rules for what counts as latest.
IDcomposer05 / 6keyless · packagist.org
Registry

Packagist

  • PackagistRegistry
  • pkg:composer

One document per vendor/name with every version inside. php and ext-* requirements skipped.

API
packagist.org
Marks
no version is ever marked
Maintainers
authors across versions, deduplicated

Lookups

Access

Createcreate("composer")
Import@agntn/registries/registries/packagist
PURLpkg:composer/vendor/name
Trypkg:composer/laravel/framework in the explorer

Address it

ts
await fetchPackageFromPURL("pkg:composer/laravel/framework");
await fetchDependenciesFromPURL("pkg:composer/laravel/framework@v13.30.1");

The vendor is the PURL namespace and it is required: pkg:composer/framework throws InvalidPURLError from the adapter, because Packagist has no package without a vendor. Versions keep their v prefix, since that is the tag name Packagist knows.

What it reads

Every call reads the same document, GET /packages/{vendor}/{name}.json, and picks a different part of it.

latestVersion is chosen by the adapter: dev-* and *-dev versions are dropped, the rest are sorted by their numeric parts with the v prefix ignored, and the highest wins. The license, keywords and dates come from that version. repository is the package's repository field, normalized.

Versions

One entry per version key in the document, with publishedAt from time, the version's own licenses combined with OR, and integrity as sha1- plus the dist shasum when there is one. Packagist has no yank flag, so status is always empty.

Dependencies

require becomes runtime, require-dev becomes development. Platform requirements, php and ext-*, are skipped; they are not packages.

Maintainers

The authors declared across versions, deduplicated by name and email, each with the role the author wrote in composer.json, when any.

URLs

ts
urls.registry("laravel/framework"); // https://packagist.org/packages/laravel/framework
urls.registry("laravel/framework", "v13.30.1"); // …/laravel/framework#v13.30.1
urls.download("laravel/framework", "v13.30.1"); // https://repo.packagist.org/p/laravel/framework/v13.30.1.json
urls.documentation("laravel/framework"); // https://packagist.org/packages/laravel/framework

Gotchas

  • A document for a package with a thousand tags is large, and every call reads it. fetchVersions on laravel/framework returns over a thousand entries.
  • Packagist's own idea of the default branch (dev-master, dev-main) never becomes latestVersion unless no tagged version exists.
  • The version sort is numeric per segment; a pre-release suffix such as -beta1 sorts by its numbers too, so v2.0.0-beta1 and v2.0.0 can compare as equal.

Where it lives

src/registries/packagist.ts.