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

@egildo/provenance

v0.8.0

Published

Knows, for one rendered document, every source involved, how the sources depend on each other, and where each came from.

Readme


A rendered document is made of many files. By the time a page appears in a browser, it has read an include tree, a configuration cascade, stylesheets, fonts, images, and whatever plugins pulled in along the way. Two questions follow every render: what did it actually load, and which files must change on disk when someone edits what they see.

Provenance is one structure that answers both. For a single rendered document, it knows every source involved, how those sources depend on each other, where each rendered thing came from, and how to stage and write changes back — without ever touching a filesystem itself.

import { openSession } from "@egildo/provenance";
import { createNodeHost } from "@egildo/provenance/node";
import { css } from "@egildo/provenance/css";
import { html } from "@egildo/provenance/html";

const session = await openSession({
  host: createNodeHost(),
  entry: "/path/to/index.html",
  handlers: [html, css],
});

for (const source of session.sources()) {
  console.log(source.id, source.state, source.location);
}

session.onChange(change => console.log(change));

Why

Most tools that need this answer it twice, with bookkeeping that can't talk to itself. BelType — the project Provenance was extracted from — kept a list of files read, a separate list of URLs loaded, two near-identical file watchers, and one hand-rolled rule mapping URLs back to files. Each piece answered one question. None of them could answer the other, because they shared no coordinates.

Provenance gives every fact — an edge, a stamp, an edit — one coordinate system: a source, a version, and a byte range. Anything it knows can be joined against anything else it knows.

What it does

  • Tracks sources of any kind. Markdown, HTML, CSS, configuration, images, fonts — and whatever a handler teaches it. Binary files are leaves: addressable, never parsed.
  • Records dependencies twice. Declared edges come from parsing; observed edges come from what a runtime actually fetched. The two are kept apart on purpose — the gap between them is the product, not noise to smooth over.
  • Addresses rendered output. Any rendered node can point back to the exact source, version, and byte range that produced it.
  • Stages edits. Changes are held against a base version, previewed in memory, and written to disk together. What gets written is exactly what the preview showed.

It runs in any JavaScript realm — Node, a browser tab, a worker — because it performs no I/O of its own. Everything outside the call (reading, writing, watching, path arithmetic) is asked of a host the embedder supplies. A Node host ships as its own entry point; nothing else in the library imports from node:, and a test enforces that rather than trusting convention.

How it decides things

Provenance is opinionated on purpose. Nine design principles govern it, each one stated as something it refuses to do:

| Principle | Forbids | |---|---| | One address space | A fact with no address. A second coordinate system past the handler boundary. | | Handlers declare; Provenance decides | A handler that reads, resolves, caches, watches, or writes. | | Derived facts are pure functions of versions | Any invalidate() call, anywhere. A cache hit that skips re-registering its probes. | | Declared and observed stay apart | An observation that overwrites a declared edge. A disagreement smoothed away. | | Source is the stored reality; renders are projections | Writing Provenance's own bookkeeping into a source file. | | Nothing touches disk before commit | Any write outside commit. A staged edit expressed against another staged edit's result. | | Edits are splices | A printer or serializer that regenerates a source from a tree. | | Languages are plugins; nesting is delegation | Language knowledge in the core. A handler parsing another language's region itself. | | Supply, not meaning | A node: import outside the Node host. A host that returns a verdict instead of a fact. |

The full reasoning — with the incidents each rule was cut from — is in the design principles.

Status

The kernel is built, and editing's first slice. Observation is not.

A session finds every source reachable from an entry document and its roots, records each declared dependency against the exact bytes that asked for it, keeps broken references visible until they heal, and reports what changed as files change. See the kernel spec for exactly what that covers, and the changelog for what shipped in each release.

Since 0.5.0 it also writes back: a tool stages an edit to a value, sees a preview, and commits it; the edit lands in exactly the bytes of that value, every other byte untouched, and survives the file changing on disk in the meantime (the design, the editing spec). Writing is granted, never ambient. Since 0.6.0 it also inserts and deletes entries (insert-delete), and an edit staged on a file that a colleague is mid-way through saving waits for it to parse again. Since 0.7.0 a commit lands every file or none (atomic-commit), and the staged edits can be saved and restored across a reload (saveable-index). Format plug-ins come from outside — Cascata's YAML and JSON writers are the first.

What's next: stamps (outputs that carry their source address, so an edit on a rendered page finds its way back), Markdown units and a CSS writer, then observation — see the vision's "What arrives first".

Install

npm install @egildo/provenance

Its tests prove write-back end to end with Cascata, a development dependency, @egildo/cascata.

Requires Node 22 or later (22.18+ to run the tests from source, for type stripping).

Entry points

| Import | What it gives you | |---|---| | @egildo/provenance | openSession and the core types | | @egildo/provenance/html | An HTML handler, on parse5 | | @egildo/provenance/css | A CSS handler, on PostCSS | | @egildo/provenance/node | The Node host | | @egildo/provenance/memory | An in-memory host, for any realm — tests, browsers, workers |

Every export is listed in the public API contract.

Who it's for

  • BelType, first — replacing its file list, URL list, two watchers, and eventually its editing server's write path.
  • Cascata, by shape and not by import — a read pass's host satisfies Cascata's Host interface structurally, so Cascata's configuration files become session roots without Cascata ever importing Provenance.
  • The CSS tools, which build on Provenance's addresses and its edit model.
  • Any tool that renders documents from files and needs to know what it read, what the runtime loaded, and how to write back.

What it deliberately stays out of — rendering, transforming, reading meaning, serving, history — is in the vision's "What it is not", each exclusion argued for.

Documentation

Development

npm test    # type-checks and runs the tests
npm run build   # writes dist/

License

MIT