# Packagist Scraper (`anyxsolutions/packagist-scraper`) Actor

Scrape PHP packages from Packagist by search term, package name, vendor, or search, package, vendor and popular URLs: latest version, license, PHP requirement, dependencies, authors, total, monthly and daily downloads, dependents, GitHub stars and abandoned status. No login, no API key.

- **URL**: https://apify.com/anyxsolutions/packagist-scraper.md
- **Developed by:** [Anyx Solutions](https://apify.com/anyxsolutions) (community)
- **Categories:** Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![banner](https://anyx.solutions/banners/packagist-scraper.png)

## Packagist Scraper

**Search Packagist or list any vendor or the most popular packages, and get each PHP package's latest version, requirements, downloads, dependents and GitHub statistics as clean JSON.**

Packagist is the main Composer repository, home to every public PHP library, framework and tool.
This Actor scrapes PHP packages from Packagist by search term, package name, vendor, or search,
package, vendor and popular URLs, and returns each package's latest version, description, license,
type, keywords, authors, maintainers, homepage and repository links, PHP version requirement,
required extensions and package dependencies, total, monthly and daily downloads, favers,
dependents, suggesters, GitHub stars, watchers, forks and open issues, release dates, and whether
the package is abandoned along with its suggested replacement. Search the way you would on
Packagist, or paste the pages you already have. There is no login, no API key, and no proxy to
configure. Built for developer-tool market research, open-source due diligence, dependency and
license audits, lead generation among PHP maintainers, and PHP ecosystem tracking.

### ⚡ Quick start

```json
{
  "searchTerms": ["web scraper"],
  "startUrls": [
    { "url": "https://packagist.org/search/?query=http%20client&type=library" }
  ],
  "maxItems": 5
}
```

Or read packages by name, and every package of a vendor:

```json
{
  "packageNames": ["guzzlehttp/guzzle", "monolog/monolog"],
  "vendors": ["spatie"],
  "maxItems": 20
}
```

### 🧩 Input

| Field                | Type    | Required | Default                      | Description                                                                                                                                                                                                                                    |
| -------------------- | ------- | -------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `searchTerms`        | array   | no       | —                            | Searches to run on Packagist, one per line, for example `web scraper` or `pdf`.                                                                                                                                                                |
| `packageNames`       | array   | no       | —                            | Packages in the `vendor/name` form Composer uses, one per line, such as `guzzlehttp/guzzle`.                                                                                                                                                   |
| `vendors`            | array   | no       | —                            | Vendors whose packages to read, one per line, such as `spatie` or `symfony`. Packages come alphabetically.                                                                                                                                     |
| `startUrls`          | array   | no       | —                            | packagist.org URLs: a search with optional tag and type filters (`/search/?query=pdf&tags=laravel&type=library`), a package (`/packages/guzzlehttp/guzzle`), a vendor (`/packages/spatie/`) or the most popular packages (`/explore/popular`). |
| `maxItems`           | integer | no       | —                            | Maximum number of packages per search term, vendor or listing URL. The input form starts at 5; leave it empty to get every match. Package names and package URLs return one package each.                                                      |
| `proxyConfiguration` | object  | no       | `{ "useApifyProxy": false }` | Proxy configuration. Packagist needs no proxy.                                                                                                                                                                                                 |

Add search terms, package names, vendors, URLs, or any mix. Search results come in Packagist's
relevance order; the popular list comes by downloads. A package URL can point at any of the
package's tabs (`/stats`, `/dependents`, `/suggesters`); the package itself is returned.

### 📤 Output

Each package is one dataset row. Release-level fields (license, keywords, authors, homepage,
requirements) describe the package's latest version: the highest stable release, else the highest
pre-release, else the default branch for a package that has never tagged a release.

#### Fields

| Field                | Type    | Description                                                                                        |
| -------------------- | ------- | -------------------------------------------------------------------------------------------------- |
| `name`               | string  | Package name, `vendor/name`.                                                                       |
| `vendor`             | string  | Vendor, the part of the name before the slash.                                                     |
| `description`        | string  | Package description.                                                                               |
| `url`                | string  | The package's page on Packagist.                                                                   |
| `repositoryUrl`      | string  | Source repository.                                                                                 |
| `homepage`           | string  | Project homepage.                                                                                  |
| `issuesUrl`          | string  | Issue tracker.                                                                                     |
| `type`               | string  | Composer package type, such as `library`, `project`, `symfony-bundle` or `wordpress-plugin`.       |
| `latestVersion`      | string  | Latest version: the highest stable release, else the highest pre-release, else the default branch. |
| `license`            | string  | License as an SPDX identifier; several licenses are joined with `OR`.                              |
| `keywords`           | array   | Keywords the authors tagged the package with.                                                      |
| `authors`            | array   | Authors as the package declares them: `name`, `email`, `homepage` and `role`.                      |
| `maintainers`        | array   | Packagist usernames of the accounts that maintain the package.                                     |
| `requirePhp`         | string  | PHP versions the latest version supports, such as `^7.4 \|\| ^8.0`.                                |
| `dependencies`       | object  | Packages the latest version requires, with their version constraints.                              |
| `dependenciesCount`  | number  | Number of packages in `dependencies`.                                                              |
| `requiredExtensions` | array   | PHP extensions the latest version requires, such as `ext-json`.                                    |
| `totalDownloads`     | number  | All-time installs.                                                                                 |
| `monthlyDownloads`   | number  | Installs over the last 30 days.                                                                    |
| `dailyDownloads`     | number  | Installs over the last day.                                                                        |
| `favers`             | number  | Favers: GitHub stars plus Packagist favorites.                                                     |
| `dependents`         | number  | Number of packages that require this one.                                                          |
| `suggesters`         | number  | Number of packages that suggest this one.                                                          |
| `githubStars`        | number  | GitHub stars; `null` for packages not hosted on GitHub.                                            |
| `githubWatchers`     | number  | GitHub watchers.                                                                                   |
| `githubForks`        | number  | GitHub forks.                                                                                      |
| `githubOpenIssues`   | number  | Open GitHub issues.                                                                                |
| `language`           | string  | Main language of the repository.                                                                   |
| `versionsCount`      | number  | Number of tagged releases (branches not counted).                                                  |
| `createdAt`          | string  | When the package was first submitted to Packagist (ISO 8601).                                      |
| `lastReleasedAt`     | string  | When the version in `latestVersion` was released (ISO 8601).                                       |
| `abandoned`          | boolean | Whether the maintainers marked the package abandoned.                                              |
| `replacement`        | string  | The package the maintainers suggest instead of an abandoned one; `null` otherwise.                 |
| `searchQuery`        | string  | The search that found the package; `null` for package names, vendors and the popular list.         |

<details><summary>Example output</summary>

```json
{
  "name": "guzzlehttp/guzzle",
  "vendor": "guzzlehttp",
  "description": "Guzzle is a PHP HTTP client library",
  "url": "https://packagist.org/packages/guzzlehttp/guzzle",
  "repositoryUrl": "https://github.com/guzzle/guzzle",
  "homepage": null,
  "issuesUrl": "https://github.com/guzzle/guzzle/issues",
  "type": "library",
  "latestVersion": "8.2.0",
  "license": "MIT",
  "keywords": [
    "framework",
    "curl",
    "http",
    "rest",
    "http client",
    "client",
    "web service",
    "psr-7",
    "psr-18"
  ],
  "authors": [
    {
      "name": "Graham Campbell",
      "email": "hello@gjcampbell.co.uk",
      "homepage": "https://github.com/GrahamCampbell",
      "role": null
    },
    {
      "name": "Michael Dowling",
      "email": "mtdowling@gmail.com",
      "homepage": "https://github.com/mtdowling",
      "role": null
    },
    {
      "name": "Jeremy Lindblom",
      "email": "jeremeamia@gmail.com",
      "homepage": "https://github.com/jeremeamia",
      "role": null
    },
    {
      "name": "George Mponos",
      "email": "gmponos@gmail.com",
      "homepage": "https://github.com/gmponos",
      "role": null
    },
    {
      "name": "Tobias Nyholm",
      "email": "tobias.nyholm@gmail.com",
      "homepage": "https://github.com/Nyholm",
      "role": null
    },
    {
      "name": "Márk Sági-Kazár",
      "email": "mark.sagikazar@gmail.com",
      "homepage": "https://github.com/sagikazarmark",
      "role": null
    },
    {
      "name": "Tobias Schultze",
      "email": "webmaster@tubo-world.de",
      "homepage": "https://github.com/Tobion",
      "role": null
    }
  ],
  "maintainers": [
    "mtdowling",
    "jeremeamia",
    "Nyholm",
    "graham-campbell",
    "mark.sagikazar"
  ],
  "requirePhp": "^7.4 || ^8.0",
  "dependencies": {
    "guzzlehttp/promises": "^3.0.2",
    "guzzlehttp/psr7": "^3.1",
    "psr/http-client": "^1.0",
    "psr/http-factory": "^1.0",
    "symfony/polyfill-php80": "^1.25",
    "symfony/polyfill-php82": "^1.27"
  },
  "dependenciesCount": 6,
  "requiredExtensions": ["ext-json"],
  "totalDownloads": 1122610765,
  "monthlyDownloads": 25572766,
  "dailyDownloads": 1125626,
  "favers": 24305,
  "dependents": 38488,
  "suggesters": 1016,
  "githubStars": 23451,
  "githubWatchers": 432,
  "githubForks": 2389,
  "githubOpenIssues": 1,
  "language": "PHP",
  "versionsCount": 185,
  "createdAt": "2014-03-15T23:44:42+00:00",
  "lastReleasedAt": "2026-09-06T13:55:09+00:00",
  "abandoned": false,
  "replacement": null,
  "searchQuery": null
}
```

</details>

### 💡 Use cases

- **Developer-tool market research** — size a PHP niche by downloads, dependents and stars, and see which packages lead it.
- **Open-source due diligence** — check how actively a package is released, by whom, which PHP versions it supports, and whether it was abandoned.
- **Dependency and license audits** — collect licenses, PHP requirements, extensions and dependencies across the packages you rely on.
- **Ecosystem tracking** — watch a vendor, a framework's tag, or the most popular packages, their releases and download trends over time.
- **Lead generation** — find the companies, agencies and maintainers behind the packages in your niche.

### ❓ FAQ

- **Do I need a Packagist account or an API key?** No. The Actor reads the same public package data anyone can see.
- **Do I need a proxy?** No. It runs without one by default.
- **How many results can one search return?** Packagist returns up to a few hundred packages for one search. Narrow it with tag and type filters, or split it into several searches, to reach more; vendors and the popular list have no such limit.
- **Which version do the release-level fields describe?** The latest version: the highest stable release, which is what Composer installs by default. Packages that only have pre-releases use the highest pre-release, and packages that never tagged a release use their default branch, such as `dev-main`.
- **What does `abandoned` mean?** The maintainers marked the package as no longer maintained. When they name a successor, it is in `replacement`.
- **Why are the GitHub fields empty for some packages?** They are only available for packages whose repository is on GitHub.
- **How fresh are the download counts?** Packagist refreshes package statistics periodically, so counts can lag by up to about half a day.

### 🔗 More scrapers by Anyx

- [npm Package Scraper](https://apify.com/anyxsolutions/npm-scraper)
- [PyPI Scraper](https://apify.com/anyxsolutions/pypi-scraper)
- [crates.io Scraper](https://apify.com/anyxsolutions/crates-io-scraper)
- [GitHub Trending Scraper](https://apify.com/anyxsolutions/github-trending-scraper)

### 🤝 Anyx Solutions

We build custom scrapers and data-extraction pipelines.

- Email: tantosthor@gmail.com

### 🖼 Image credit

Image credit: [packagist.org](https://packagist.org/)

# Actor input Schema

## `searchTerms` (type: `array`):

Searches to run on Packagist, one per line, for example web scraper or pdf. Results come in Packagist's relevance order.

## `packageNames` (type: `array`):

Packages to read directly, one per line, in the vendor/name form Composer uses, for example guzzlehttp/guzzle or monolog/monolog.

## `vendors` (type: `array`):

Vendors whose packages to read, one per line, for example spatie or symfony. Packages come in alphabetical order.

## `startUrls` (type: `array`):

packagist.org pages: a search with optional tag and type filters (https://packagist.org/search/?query=pdf\&tags=laravel\&type=library), a package (https://packagist.org/packages/guzzlehttp/guzzle), a vendor (https://packagist.org/packages/spatie/) or the most popular packages (https://packagist.org/explore/popular).

## `maxItems` (type: `integer`):

Maximum number of packages to return per search term, vendor or listing URL. Leave empty to get every match. Package names and package URLs always return one package each.

## `proxyConfiguration` (type: `object`):

Proxy settings. Packagist is public and needs no proxy.

## Actor input object example

```json
{
  "searchTerms": [
    "web scraper"
  ],
  "startUrls": [
    {
      "url": "https://packagist.org/search/?query=http%20client&type=library"
    }
  ],
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "web scraper"
    ],
    "startUrls": [
        {
            "url": "https://packagist.org/search/?query=http%20client&type=library"
        }
    ],
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("anyxsolutions/packagist-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["web scraper"],
    "startUrls": [{ "url": "https://packagist.org/search/?query=http%20client&type=library" }],
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("anyxsolutions/packagist-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "web scraper"
  ],
  "startUrls": [
    {
      "url": "https://packagist.org/search/?query=http%20client&type=library"
    }
  ],
  "maxItems": 5
}' |
apify call anyxsolutions/packagist-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,anyxsolutions/packagist-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AxfUjLEGRyoNgJZop/builds/I79QvhAZoslWbkA6D/openapi.json
