Datadog collects and monitors your PHP app metrics and distributed traces in real-time with application performance monitoring. Decrease downtime and performance issues with Datadog APM by tracing requests across service boundaries and drilling into individual traces end-to-end with flame graphs. Start your 14-day trial for free today.

Getting package statistics from Packagist

Original – by Freek Van der Herten – 2 minute read

At my work I'm currently creating a new dashboard. That's a fancy term for an html page sprinkled with some Vue magic that will be displayed on tv screen at the wall of our office. I won't say much about the dashboard itself on this post, but I'll make sure to write something on that in the near future.

One of the things I want to display on our dashboard is how many times our packages get downloaded (yeah it's a vanity project, sorry about that :-)). To make this real easy our intern Jolita and I cooked up a new package called packagist-api. It uses the packagist api to fetch data about published packages.

Once installed you can to this:

$client = new \GuzzleHttp\Client();

$packagist = new \Spatie\Packagist\Packagist($client);

//returns a list of all packages by a vendor

//returns statistics on a specific package

That last call will return a big array with all info on a given package:

     "package" => [
       "name" => "spatie/laravel-fractal",
       "description" => "A Fractal service provider for Laravel 5",
       "time" => "2015-10-06T13:33:09+00:00",
       "maintainers" => [
           "name" => "spatie",
       "versions" => [
         "dev-master" => [
           "name" => "spatie/laravel-fractal",
           "description" => "A Fractal service provider for Laravel 5",
           "keywords" => [


       "downloads" => [
         "total" => 18844,
         "monthly" => 4859,
         "daily" => 18,
       "favers" => 142,

This code will get the daily, monthly and total number of downloads for our packages:

$totals = collect($packagist->getPackagesByVendor('spatie')['packageNames'])
    ->map(function ($packageName) use ($packagist) {
        return $packagist->findPackageByName($packageName)['package'];
    ->reduce(function ($totals, $packageProperties) {

        foreach ($totals as $sumName => $total) {
            $totals[$sumName] += $packageProperties['downloads'][$sumName] ?? 0;

        return $totals;
    }, ['daily' => 0, 'monthly' => 0, 'total' => 0]);

This will output this array:

  "daily" => 423
  "monthly" => 94876
  "total" => 473184

Now the only thing that's bothering me is that foreach-loop in the reduce. Hopefully after reading Adam Wathan's new book on refactoring to collections I'll come up with a more elegant solution. If you have a suggestion on how to make the code better, let me know in the comments below.

EDIT: I did manage to get the code better using a pipe macro.

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.