npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@b-apm/core

v0.1.0

Published

Core library for bapm: manifest, lockfile, resolver, install, adapters

Readme

@b-apm/core

UNSTABLE: Early public release. APIs and on-disk layouts may change without a major bump. Not production-ready.

Domain library for bapm (Better Agent Package Manager): manifest, lockfile, resolver, install, adapters.

Manifest (M1)

Public API for project manifests:

  • discoverManifestPath({ cwd?, path? }) — resolve which file to load
  • loadManifest({ cwd?, path? }) — discover → read → safe YAML → validate
  • parseManifest / parseManifestDocument — validate an already-parsed JS object
  • Constants: APM_MANIFEST_FILE (apm.yml), BAPM_MANIFEST_FILE (bapm.yml)

Dual-file discovery

  • Explicit path always wins (no sibling-name search).
  • Otherwise project root is cwd (default process.cwd()); no parent walk-up.
  • Only apm.yml → load it; only bapm.yml → load it; both → hard error (no merge); neither → error.
  • Result metadata includes sourcePath / sourceFilename so a future rewrite MUST write back to the same filename (never auto-create the sibling brand name). Rewrite/mf-006 itself is deferred past M1.

OpenAPM-strict YAML

Load rejects YAML anchors/aliases and custom tags (OpenAPM req-mf-020). This is intentionally stricter than APM’s budgeted SafeLoader when APM would accept anchors within an expansion budget.

Validation covers required name/version strings, dependency/registry shapes (including git+path companion, required path for git: parent, registries.default as a name pointer, and allowlisted dep meta such as alias), unknown/x-* retention on the in-memory document, workspaces reject, and mutual exclusion of target+targets. M1 does not resolve, lock, download, or install.

See the monorepo root README and OpenSpec change m1-manifest-yaml-dual-read.

Lockfile (M2)

Public API for project lockfiles (apm.lock.yaml / bapm.lock.yaml):

  • discoverLockfilePath({ cwd?, path? }) — resolve which file to load
  • loadLockfile({ cwd?, path? }) — discover → read → safe YAML → validate (strict)
  • loadLockfileOrNull({ cwd?, path? }) — same, but null when neither brand file exists
  • parseLockfile / parseLockfileDocument — validate YAML text or an already-parsed JS object
  • serializeLockfile(document) → YAML string
  • writeLockfile(document, { cwd?, path?, sourcePath?, sourceFilename? })
  • isSemanticallyEquivalent(a, b) — ignores generated_at / apm_version
  • Constants: APM_LOCK_FILE (apm.lock.yaml), BAPM_LOCK_FILE (bapm.lock.yaml)

Dual-file discovery

  • Explicit path always wins (no sibling-name search).
  • Otherwise project root is cwd (default process.cwd()); no parent walk-up.
  • Only apm.lock.yaml → load it; only bapm.lock.yaml → load it; both → hard error (no merge); neither → not-found (loadLockfileOrNullnull).
  • Legacy apm.lock (non-.yaml) is out of M2 dual-read.
  • Write-back uses the loaded filename/sourcePath; fresh create without path → bapm.lock.yaml. Never auto-create the sibling brand.

Emit policy (OpenAPM-preferring)

  • Always emit explicit lockfile_version.
  • Force "2" when any source: registry (and MAY bump for git-semver fields).
  • Monotonic: never demote loaded "2""1" (stricter than APM demotion).
  • Sort dependencies by (repo_url, virtual_path) (OpenAPM req-lk-005; not APM (depth, repo_url)).
  • Normalize bare 64-hex hashes to sha256:<hex> on read; emit envelopes on write.
  • Preserve unknown / x-* / APM deployments / lsp_* bags on round-trip.

Out of M2

M2 does not resolve, download, install, run frozen CI, materialize integrations, or invoke @b-apm/integration-* adapters.

See OpenSpec change m2-lockfile-yaml-dual-read.