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

@moult/runtime

v0.1.2

Published

A general plugin runtime for safe replacement.

Readme

@moult/runtime

A general plugin runtime for safe replacement.

A plugin is a versioned capability provider running inside an owned resource scope. A replacement is prepared in isolation, committed only after successful preparation, and followed by disposal of the previous generation.

The name is the mechanism: a crab grows a new exoskeleton beneath the old one and sheds the old shell only after the new one is complete. A failed moult leaves the old shell intact.

What it guarantees

  • Failed replacement is invisible. A candidate whose setup throws is disposed completely; the previous generation stays active and usable (INV-01/07).
  • Commit is atomic. Staged capabilities and contributions are invisible until commit, and the old generation is never restored after it (INV-06/08).
  • Every resource has an owner. Disposal runs LIFO, continues after individual failures, and leaves zero live resources behind (INV-02/03/12).
  • Dependents are respected. Stopping a provider with active dependents is rejected unless you ask for an explicit, ordered, recorded cascade (INV-11); replacing a provider whose dependents are active is rejected in v1 (INV-15).
  • Nothing global. Instances share nothing; resolution is deterministic; every failure is a structured MoltError with a stable code (INV-10/13).

Install

npm install @moult/runtime

Node ≥ 22. Dual ESM/CJS, one runtime dependency (semver).

Related packages

Example

import { capability, createRuntime } from '@moult/runtime';

const storage = capability<{ get(key: string): string | undefined }>('storage', '1.0.0');

const runtime = createRuntime();
runtime.install({
  id: 'memory.storage',
  version: '1.0.0',
  provides: [{ capability: storage }],
  setup: (context) => {
    const map = new Map<string, string>();
    context.provide(storage, { get: (key) => map.get(key) });
  },
});
await runtime.start('memory.storage');

// A broken replacement leaves the old generation serving:
await runtime.replace({
  id: 'memory.storage',
  version: '2.0.0',
  provides: [{ capability: storage }],
  setup: () => {
    throw new Error('bug in the new version');
  },
}); // rejects — and memory.storage is still active

Status

Implemented and published. The design notes and the full invariant registry (INV-01…INV-15) live in the repository under docs/. See the root README for scope, non-goals, and how Moult compares to Effect, TC39 using, and Cordis.

Documentation

See the Moult repository, the lifecycle guarantees, and the adapter design.