One PURL. Every registry.
One TypeScript interface over npm, PyPI, crates.io, RubyGems, Packagist and Arch Linux. Package, versions, dependencies and maintainers come back in the same shape, from a CLI, a library call, or an AI SDK tool.
- 6
- registries
- 4
- lookups
- 1
- package shape
- 5
- AI tool operations
Lookups
PURL in, package out
A package URL names the ecosystem, the namespace, the name and the version. The library parses it once, picks the adapter, asks the registry, and hands back one Package. The panel cycles through 6 packages and swaps each recorded sample for the docs worker's live answer.
- pkg:npm/lodash, pkg:cargo/serde, pkg:alpm/aur/paru: one addressing scheme, ECMA-427
- License normalized to SPDX, repository URL canonicalized, versions dated
- A missing package is a typed NotFoundError, never an empty object
awaitfetchPackageFromPURL("pkg:npm/lodash")
Lodash modular utilities.
- licenses
- MIT
- repository
- github.com/lodash/lodash
- homepage
- lodash.com
- versions
- 117newest 4.18.1 · 2026-04-01
- keywords
- modules, stdlib, util
One interface
Same calls, every adapter
Every registry is a class with the same four methods and a URL builder. Swap the PURL and the rest of the code stays. Upstream quirks, from npm's dist-tags to the AUR's RPC, are normalized inside the adapter and never leak through the public types.
- fetchPackage, fetchVersions, fetchDependencies, fetchMaintainers on every registry
- Adapters register themselves; create('npm') resolves the class, no switch statement
- Bring your own Client for retries, timeouts, rate limiting and a User-Agent
import { fetchPackageFromPURL } from "@agntn/registries";
const pkg = await fetchPackageFromPURL("pkg:npm/lodash");
pkg.latestVersion; // "4.18.1"
pkg.licenses; // "MIT"
pkg.repository; // "https://github.com/lodash/lodash"
// same shape from NpmRegistry as from every other adapterCLI and cache
A terminal client with a lockfile
The same lookups from a shell. Answers are cached under the platform cache directory with a lockfile that records when each entry was fetched and how long it stays fresh, so a second call for the same package never leaves the machine.
- registries info, versions, deps, maintainers, with --json for scripts
- Cache on unstorage with sha256 integrity and a TTL per data type
- Filesystem by default, any unstorage driver on the edge
$registries versions npm/lodash --limit 4
117 total
| version | published | licenses | status |
|---|---|---|---|
| 4.18.1 | 2026-04-01 | MIT | ok |
| 4.18.0 | 2026-03-31 | MIT | deprecated |
| 4.17.23 | 2026-01-21 | MIT | ok |
| 4.17.21 | 2021-02-20 | MIT | ok |
0 dependencies at 4.18.1 ·2 maintainers
Registries
Six adapters, one shape
Each adapter maps one registry API onto the shared types. Adding one means writing the mapping, not the HTTP client, the retry policy or the cache.
- npm scopes, Composer vendors and Arch namespaces handled in the PURL
- Yanked, deprecated and flagged versions carry a status, not a footnote
- A custom adapter is one class and one register() call
Agents
One tool for the AI SDK
packageTool from the /ai subpath is a Vercel AI SDK tool that needs no wiring. Hand it to a model and it resolves any PURL it is asked about, with the same normalized answer the CLI prints.
- package, versions, dependencies, maintainers and bulk-packages behind one input schema
- Input validated with Zod, abort signal passed through to every registry call
- Bulk lookups skip a failed package instead of failing the batch
toolpackageTool
@agntn/registries/ai · Vercel AI SDK
input
{
"operation": "package",
"purl": "pkg:npm/lodash"
}output
{
"name": "lodash",
"namespace": "",
"latestVersion": "4.18.1",
"licenses": "MIT",
"repository": "https://github.com/lodash/lodash",
"keywords": ["modules","stdlib","util"],
…
}Start with one command
Pre-1.0. Pin exact versions, and treat registry metadata as data you did not write.