# JSR Registry Scraper (`crawlerbros/jsr-registry-scraper`) Actor

Search and scrape JSR (jsr.io) - the JavaScript Registry - for package metadata, quality scores, GitHub links, runtime compatibility, scopes, and dependents. Pure public API, no auth.

- **URL**: https://apify.com/crawlerbros/jsr-registry-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## JSR Registry Scraper

Search and scrape [JSR](https://jsr.io) — the JavaScript Registry (Deno's modern package registry for JavaScript and TypeScript) — for package metadata, quality scores, GitHub links, runtime compatibility, scopes, and dependents. Pure public API, no auth, no proxy.

### What this actor does

- **Seven modes:** `search`, `byPackages`, `byScope`, `dependents`, `dependencies`, `versions`, `trending`
- **Rich metadata:** quality score, GitHub repo link, runtime compatibility (Deno/Node/Browser/Cloudflare Workers/Bun), version/dependency/dependent counts
- **Optional enrichment:** license, provenance, and score-breakdown details per package (mode=byPackages, trending)
- **Filters:** min quality score, runtime compatibility, exclude archived, require GitHub link
- **Empty fields are omitted** — every field in the output is real, populated data

### Output fields

#### `package` records (`mode=search`, `byPackages`, `byScope`, `trending`)

- `packageId` (`@scope/name`), `scope`, `name`, `description`
- `githubOwner`, `githubRepo`, `githubUrl`
- `compatibleRuntimes[]` — subset of `deno`/`node`/`browser`/`workerd`/`bun`
- `versionCount`, `dependencyCount`, `dependentCount`, `score` (0-100)
- `latestVersion`, `updatedAt`, `createdAt`, `whenFeatured`, `isArchived`, `readmeSource`
- `packageUrl`, `latestVersionUrl`
- With `enrichDetails=true` (mode=byPackages, trending): `hasReadme`, `hasReadmeExamples`, `allEntrypointsDocs`, `allFastCheck`, `hasProvenance`, `hasDescription`, `atLeastOneRuntimeCompatible`, `multipleRuntimesCompatible`, `percentageDocumentedSymbols`, `scoreTotal`, `license`, `latestVersionYanked`, `usesNpm`, `hasProvenanceLog`
- mode=trending only: `statsCategory` (`newest`/`updated`/`featured`), `statsVersion` (for `updated` category)
- `recordType: "package"`, `scrapedAt`

#### `scope` record (`mode=byScope`, emitted once per scope)

- `scope`, `description`, `createdAt`, `updatedAt`, `scopeUrl`
- `recordType: "scope"`, `scrapedAt`

#### `dependent` records (`mode=dependents`)

- `packageId`, `scope`, `name`, `dependentVersions[]`, `dependentTotalVersions`, `packageUrl`, `dependencyOf`
- `recordType: "dependent"`, `scrapedAt`

#### `dependency` records (`mode=dependencies`, of the package's latest version)

- `kind` (`jsr` or `npm`), `name`, `constraint` (semver range), `path` (sub-path export, if any), `dependencyUrl`
- `dependencyOf` (`@scope/name`), `dependencyOfVersion`
- `recordType: "dependency"`, `scrapedAt`

#### `version` records (`mode=versions`, full publish history of a package)

- `packageId`, `scope`, `name`, `version`, `versionUrl`
- `publishedByName`, `publishedByGithubId`, `publishedByAvatarUrl`
- `yanked`, `usesNpm`, `hasProvenanceLog`, `readmePath`, `publishedAt`
- `recordType: "version"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byPackages` / `byScope` / `dependents` / `dependencies` / `versions` / `trending` |
| `searchQuery` | string | – | Free-text query (mode=search) |
| `packages` | array | – | Package specifiers, e.g. `@std/testing` (mode=byPackages, dependents, dependencies, versions) |
| `scope` | string | – | Scope name without `@`, e.g. `std` (mode=byScope) |
| `statsCategory` | string | `all` | `all` / `featured` / `newest` / `updated` (mode=trending) |
| `minScore` | int | – | Drop packages below this quality score (0-100) |
| `runtime` | string | – | Only keep packages compatible with this runtime |
| `excludeArchived` | bool | `false` | Drop archived packages |
| `requireGithub` | bool | `false` | Only keep packages with a linked GitHub repo |
| `enrichDetails` | bool | `true` | Fetch score-breakdown + license per package (mode=byPackages, trending) |
| `maxItems` | int | `50` | Hard cap (1–1000) |

#### Example: search for well-maintained Deno-compatible testing packages

```json
{
  "mode": "search",
  "searchQuery": "testing",
  "runtime": "deno",
  "minScore": 70,
  "excludeArchived": true,
  "maxItems": 50
}
```

#### Example: lookup specific packages with full enrichment

```json
{
  "mode": "byPackages",
  "packages": ["@std/testing", "@oak/oak", "@hono/hono"],
  "enrichDetails": true
}
```

#### Example: browse an entire scope

```json
{
  "mode": "byScope",
  "scope": "std",
  "maxItems": 100
}
```

#### Example: find what depends on a package

```json
{
  "mode": "dependents",
  "packages": ["@std/testing"],
  "maxItems": 100
}
```

#### Example: list what a package depends on

```json
{
  "mode": "dependencies",
  "packages": ["@oak/oak"]
}
```

#### Example: full version/publish history of a package

```json
{
  "mode": "versions",
  "packages": ["@std/testing"],
  "maxItems": 100
}
```

#### Example: trending / newest / featured packages

```json
{
  "mode": "trending",
  "statsCategory": "featured",
  "enrichDetails": true
}
```

### Use cases

- **Dependency research** — audit quality scores, licenses, and runtime compatibility before adopting a package
- **Ecosystem analysis** — map dependents of a popular package to gauge its influence
- **Security / supply-chain review** — check for GitHub provenance, archived status, and npm interop
- **Package discovery** — find packages by keyword filtered to your target runtime (e.g. Cloudflare Workers)
- **Registry monitoring** — track new/updated packages within a scope over time

### FAQ

**Do I need a login or API key?** No — this uses JSR's own public `api.jsr.io` REST API, which requires no authentication.

**What is JSR?** [jsr.io](https://jsr.io) is a modern package registry for JavaScript/TypeScript built by the Deno team, designed to work across Deno, Node.js, Bun, browsers, and Cloudflare Workers, with first-class TypeScript support and automatic API documentation.

**What's the difference between `score` and the `enrichDetails` breakdown fields?** `score` (0-100) is a single quality metric always included. The breakdown fields (`hasReadme`, `allFastCheck`, `percentageDocumentedSymbols`, etc.) explain what contributes to that score — only fetched in `byPackages` mode with `enrichDetails=true`.

**Why do some packages have no `score` or `latestVersion`?** JSR scopes can be reserved before any version is published — such packages have `versionCount: 0` and legitimately lack a score, license, or GitHub link. These fields are omitted rather than filled with placeholders.

**How fresh is the data?** Real-time — every run queries JSR's live API directly.

**Why does `dependencyUrl` sometimes point to npmjs.com and sometimes to jsr.io?** JSR packages can depend on either other JSR packages or npm packages directly (`mode=dependencies`). `kind: "jsr"` deps link to `jsr.io`; `kind: "npm"` deps link to `npmjs.com`. Note npmjs.com serves a bot-challenge page to non-browser HTTP clients (`curl`), but the URL itself is correct and opens normally in a browser.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

## `searchQuery` (type: `string`):

Free-text query (mode=search), e.g. `testing`, `oak`, `hono`.

## `packages` (type: `array`):

Package specifiers, e.g. `@std/testing`, `std/testing`, or a full jsr.io URL. mode=dependents/dependencies/versions uses only the first entry.

## `scope` (type: `string`):

JSR scope name without the `@`, e.g. `std`, `deno`.

## `statsCategory` (type: `string`):

Which curated JSR list to pull package details from.

## `minScore` (type: `integer`):

Drop packages with a JSR quality score below this (0-100).

## `runtime` (type: `string`):

Only keep packages compatible with this runtime.

## `excludeArchived` (type: `boolean`):

Drop packages marked as archived.

## `requireGithub` (type: `boolean`):

Only keep packages that have a linked GitHub repository.

## `enrichDetails` (type: `boolean`):

Fetch additional score-breakdown and license details per package (mode=byPackages/trending only; 2 extra requests per package).

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "testing",
  "packages": [
    "@std/testing"
  ],
  "scope": "std",
  "statsCategory": "featured",
  "runtime": "",
  "excludeArchived": false,
  "requireGithub": false,
  "enrichDetails": true,
  "maxItems": 30
}
```

# Actor output Schema

## `records` (type: `string`):

Dataset containing all scraped packages / scopes / dependents.

# 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 = {
    "mode": "search",
    "searchQuery": "testing",
    "packages": [
        "@std/testing"
    ],
    "scope": "std",
    "statsCategory": "featured",
    "runtime": "",
    "excludeArchived": false,
    "requireGithub": false,
    "enrichDetails": true,
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/jsr-registry-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 = {
    "mode": "search",
    "searchQuery": "testing",
    "packages": ["@std/testing"],
    "scope": "std",
    "statsCategory": "featured",
    "runtime": "",
    "excludeArchived": False,
    "requireGithub": False,
    "enrichDetails": True,
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/jsr-registry-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 '{
  "mode": "search",
  "searchQuery": "testing",
  "packages": [
    "@std/testing"
  ],
  "scope": "std",
  "statsCategory": "featured",
  "runtime": "",
  "excludeArchived": false,
  "requireGithub": false,
  "enrichDetails": true,
  "maxItems": 30
}' |
apify call crawlerbros/jsr-registry-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/jsr-registry-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/ts78zEK6h5PT9pCcp/builds/8VrR6yGz1XdUf3555/openapi.json
