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

@projectpac/core-host

v0.6.0

Published

Part of PAC: @projectpac/core-host.

Readme

@projectpac/core-host

Claims ctx.host. The install lifecycle over the plugins tree, the package source seam, and each plugin's own directory.

It keeps no record of its own. plugins.yml is what is installed, a plugin's manifest is what its module exports, and what vouched for a fetched package rides on its row. One truth about the installed set, so nothing has to be kept in step with it: the registry this replaced listed rows the tree did not run and missed the ones setup had seeded.

Installing writes a row. Two ways to ask. { package } names something the node does not have: an enabled package source fetches it into the node's module directory (<data dir>/modules, an npm prefix), the host reads the manifest out of the package's own metadata -- executing nothing -- and the row carries what the source said vouched for the bytes. { source, id } names a module the node already has, seeded by setup or linked by a dev lane; its caller names the row, because nothing fetched it and nothing vouches for it.

requireVouched is the one policy. Off by default, because installing code is the trust decision and a signature says who produced the bytes rather than whether they are safe. On, a fetched package its source could not verify is refused, and so is every { source } install.

It does not sit between an installed plugin and the core plugins. A loaded plugin reaches them directly and each one derives its caller, so the host's job ends once an entry exists.

Disabling is enough. Everything a plugin registered is an effect of its scope, so one flag withdraws its advertisements, routes, served resources, and workspaces. kill differs only in what a restart does: a killed plugin comes back, a disabled one does not. A plugin's background work is its own -- a timer inside one of its effects goes with the rest.

A plugin's directory is the node's, not the host's. dirFor resolves <data dir>/<id> off the data directory rather than under anything of the host's: nesting it would make removing the host mean removing everything every plugin ever kept.

Removing a plugin does not take its directory. The host dispatches core/removing into the plugin while it is still running and waits, and what the plugin leaves behind is what a later install of the same id will find -- databases, files, all of it. Clearing it is the plugin's to do, and the signal is its chance. The cost is that a plugin which ignores the signal leaves a folder nothing lists; the reason is that a node should not destroy the principal's own material because a plugin that merely read it was removed.

ctx.self is one service that answers per caller -- see binding.ts. A service rather than an accessor, because a plugin declares inject: ["self"] and cordis gates an inject on a service being available. self rather than plugin because cordis already declares plugin() on Context.

layer.ts holds two refusals, both about names the node has already claimed: a plugin id may not collide with a name the node's own state uses on disk, and a fetched package may not claim a spine service key. The first is checked at install and again where the directory is created, which is what covers a row written into the entry file by hand and a row setup named for the first boot. The second can only run where a manifest is in hand before the row is written, which is a fetched package; a { source } install that claims one is refused by the framework when its module loads.