spatie/packagist-api
Search Packagist and fetch package details via the official Packagist API. Provides a simple PackagistClient built on Guzzle with a URL generator, plus helpers to list all packages or filter by vendor/type, and browse popular packages with pagination.
Installation:
composer require spatie/packagist-api
No additional configuration is required—just autoload the package.
First Use Case:
Fetch basic package info (e.g., laravel/framework):
use Spatie\PackagistApi\Packagist;
$packagist = new Packagist();
$package = $packagist->find('laravel/framework');
dd($package->name, $package->description, $package->version);
Key Classes:
Spatie\PackagistApi\Packagist: Main facade for API interactions.Spatie\PackagistApi\Models\Package: Represents a Packagist package (e.g., laravel/framework).Spatie\PackagistApi\Models\PackageVersion: Represents a specific version of a package.src/Packagist.php for available methods.// Get a single package
$package = $packagist->find('spatie/laravel-backup');
// Get all versions of a package
$versions = $packagist->findVersions('spatie/laravel-backup');
// Search by keyword (returns a collection of Package objects)
$results = $packagist->search('laravel', 10); // Limit to 10 results
// Get a specific version
$version = $packagist->findVersion('laravel/framework', '10.0.0');
// Compare versions (e.g., check if a version is stable)
if ($version->isStable()) {
// Logic for stable versions
}
// Get dependencies for a package/version
$dependencies = $packagist->findVersion('spatie/laravel-backup', '6.0.0')->dependencies;
// Check if a package requires PHP 8.0+
$phpVersion = $packagist->find('spatie/laravel-backup')->require->php;
The package uses PSR-6 caching (via Spatie\PackagistApi\Cache\Cache). Configure it in config/packagist-api.php:
'cache' => [
'driver' => 'file', // or 'array', 'database', etc.
'prefix' => 'packagist_',
],
Enable caching for frequent requests:
$packagist = new Packagist(config('packagist-api.cache'));
Bind the Packagist class to the container for easy dependency injection:
// In AppServiceProvider
$this->app->singleton(Packagist::class, function ($app) {
return new Packagist(config('packagist-api.cache'));
});
Now inject it anywhere:
public function __construct(private Packagist $packagist) {}
Useful for CLI tools (e.g., checking package compatibility):
use Spatie\PackagistApi\Packagist;
class CheckPackageCommand extends Command {
protected $signature = 'package:check {package}';
protected $description = 'Check package metadata';
public function handle(Packagist $packagist) {
$package = $packagist->find($this->argument('package'));
$this->info("Package: {$package->name}");
$this->line("Latest version: {$package->version}");
}
}
Trigger actions when package updates are detected (e.g., for a "Package Monitor"):
$packagist = new Packagist();
$latestVersion = $packagist->find('spatie/laravel-backup')->version;
if ($latestVersion !== cache('last_backup_version')) {
cache()->put('last_backup_version', $latestVersion);
event(new PackageUpdated($packageName, $latestVersion));
}
Mock the Packagist class in tests:
$mock = Mockery::mock(Packagist::class);
$mock->shouldReceive('find')
->with('spatie/laravel-backup')
->andReturn((new Package())->setName('spatie/laravel-backup'));
$this->app->instance(Packagist::class, $mock);
Rate Limiting:
429 responses.try {
$package = $packagist->find('laravel/framework');
} catch (RateLimitExceededException $e) {
sleep(60); // Wait for rate limit to reset
retry();
}
Deprecated Packages:
null or throw exceptions if they’re deleted from Packagist. Handle gracefully:
$package = $packagist->find('nonexistent/package');
if (!$package) {
$this->error('Package not found on Packagist.');
}
Version Parsing:
PackageVersion model includes methods like isStable(), isDev(), and isRC(), but edge cases (e.g., custom version strings) may break parsing. Validate versions manually if needed:
if (!Version::isValid($versionString)) {
throw new InvalidArgumentException("Invalid version format: {$versionString}");
}
Caching Invalidation:
// Clear cache every hour
$schedule->command('cache:clear')->hourly();
Enable Debugging:
Set the debug config option to log API requests:
'debug' => env('PACKAGIST_DEBUG', false),
Check logs for raw API responses.
API Response Inspection:
The Packagist class returns Spatie\PackagistApi\Models\Package objects, but you can access the raw response via:
$rawResponse = $packagist->getRawResponse('laravel/framework');
Common Exceptions:
PackageNotFoundException: Thrown when a package doesn’t exist.InvalidArgumentException: Invalid package name/version format.RateLimitExceededException: Hit API rate limits.Batch Fetching:
For multiple packages, use findMany() to reduce API calls:
$packages = $packagist->findMany(['laravel/framework', 'spatie/laravel-backup']);
Version Comparison:
Use the Version helper class for semantic versioning:
use Spatie\PackagistApi\Support\Version;
if (Version::isGreaterThan('10.0.0', '9.0.0')) {
// Logic for newer versions
}
Custom Endpoints:
The package wraps Packagist’s API but doesn’t expose all endpoints. For unsupported endpoints (e.g., /packages.json), extend the Packagist class:
class CustomPackagist extends Packagist {
public function getPackagesJson() {
return $this->get('https://packagist.org/packages.json');
}
}
Performance:
dependencies only when needed to avoid heavy API responses.findVersion() instead of find() if you need specific version data.Local Development: Mock the API during development to avoid hitting rate limits:
$packagist = new Packagist(['cache' => ['driver' => 'array']]);
$packagist->setBaseUrl('http://localhost:8000'); // Point to a local Packagist instance
How can I help you explore Laravel packages today?