jordanpartridge/packagist-client
A lightweight PHP client for the Packagist API that lets Laravel and PHP apps query package metadata, versions, and download stats through a simple, expressive wrapper. Clean Laravel integration with config and service container support.
This is the first tagged release (v0.1.0a) of jordanpartridge/packagist-client, so treat everything below as a baseline to diff future releases against — the release notes contain only a changelog link, meaning there is no documented feature list, migration path, or stability guarantee yet. Verify the public surface yourself before designing around it.
composer require jordanpartridge/packagist-client:0.1.0a — pin the exact alpha version, do not use ^0.1 if you care about reproducibility.composer.json for the Laravel version constraint and whether the service provider is auto-discovered (extra.laravel.providers / aliases). If not, register it manually in config/app.php.php artisan vendor:publish --provider="...ServiceProvider" and inspect the resulting config/packagist.php for base URI, cache TTL, timeout, and any token/User-Agent settings.src/ for the entry point (client class or facade) and tests/ for the intended calling convention — the tests are the most reliable documentation at this stage.First use case: resolve a package's metadata (latest stable version, description, repository URL, download counts) for a single vendor/name pair and dump it in php artisan tinker. That confirms wiring, transport, and response shape in one step before you build anything on top.
Wrap it in your own adapter. Do not inject the package's client directly into controllers, commands, or jobs. Put a small PackagistRepository/PackageInfo interface in your domain layer and implement it with the package. Alpha clients rename classes; your adapter absorbs that.
Prefer constructor injection over the facade in anything you intend to test. If the package only exposes a facade, bind your adapter in a service provider and keep the facade usage confined to that one implementation class.
Cache aggressively at your boundary, not theirs. Packagist data changes on the order of minutes-to-hours, not seconds. Wrap calls in Cache::remember() with a key that includes the package name and the stability flag, and set TTL from your own config rather than relying on any package-level default (which may be absent in a 0.1.0).
Bulk work belongs in queued jobs. If you are auditing many dependencies — checking for abandoned packages, outdated constraints, or unmaintained transitive deps — dispatch one job per package with ->delay() spread across time. This keeps you under rate limits and makes retries granular and observable.
A natural integration point is a Composer-adjacent Artisan command. Read composer.lock, extract packages[].name, resolve each against the client, and emit a table or JSON report. Schedule it weekly and diff against the previous run to surface newly abandoned or yanked packages.
In tests, fake the HTTP layer. Http::fake() with fixture JSON is far more reliable than hitting the network, and it lets you assert the exact request URI and headers your adapter produces.
0.1.0a with an empty changelog means method signatures, return types (array vs DTO), and config keys can all move. Pin the version, keep the adapter thin, and re-read the source on every bump rather than assuming semver protects you.User-Agent. Requests without one that names your application and a contact URL are liable to be blocked or throttled. Set it in config or per-request; verify the package does not ship a generic default.vendor/name typos and private packages not on Packagist both produce a not-found response — do not let it throw an unhandled exception into a loop over composer.lock.latest, latest-stable, or a version satisfying a constraint, and be explicit — the default may not be what you expect.Http::retry() or your own retry loop; bulk scans over a few hundred packages will hit limits otherwise.^8.0", the constraint must be part of the cache key, or a dependency bump will silently serve stale results.How can I help you explore Laravel packages today?