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

rfc-extract

v0.3.0

Published

Turn an IETF RFC into a markdown knowledge base

Readme

rfc-extract

Turns an IETF RFC into a folder of markdown that an agent can grep and a human can read.

rfc-extract 9421
~/.local/share/rfc-kb/rfc9421/
  README.md              title, abstract, source tier, navigation
  meta.json              number, date, authors, sha256, tier, extraction date
  sections/              one file per top-level section, with frontmatter
  requirements.md        every BCP 14 paragraph, grouped by section
  requirements.json      the same records, machine-readable
  abnf/                  grammar this RFC defines
  examples/              one file per code block, typed extension
  references.md          normative and informative, with citing sections
  iana.md                what the RFC asks IANA to register
  errata.md              published errata with status
  notes/                 yours, never touched by the tool

The derived views are the useful part. requirements.json is the conformance checklist you would otherwise build by hand, every example is a file you can pipe into a test, and each paragraph keeps the RFC's own anchor, so req-2.1-17 locates its own source in the published document.

To let an agent read the result over MCP, see rfc-mcp.

Install

Needs Node 22 or newer.

npm install -g rfc-extract

Or without installing:

npx rfc-extract 9421

From a clone:

git clone https://github.com/cozminu/rfc-tools.git
cd rfc-tools
pnpm install
pnpm build
node packages/rfc-extract/dist/cli.js 9421

CLI

rfc-extract <rfc-number | rfcNNNN | url> [options]

All three of 9421, rfc9421, and https://www.rfc-editor.org/rfc/rfc9421.html resolve to the same RFC.

| Flag | Effect | | --- | --- | | --out <dir> | output root, default ~/.local/share/rfc-kb (see below) | | --no-errata | skip the errata dump | | --refresh | ignore the HTTP cache | | --json | machine-readable run summary on stdout | | --help | print usage |

| Exit code | Meaning | | --- | --- | | 0 | success | | 1 | unsupported source tier (a legacy RFC) | | 2 | network or fetch failure, or bad arguments | | 3 | parse failure | | 4 | emit failure |

The KB is rebuilt in place and is deterministic for the same input, so a committed KB shows only real changes in git. notes/ survives every re-run.

Where things go

A knowledge base is user-level data, not a property of the directory you ran from, so both defaults live under your home directory and are shared by every project.

| What | Default | Overrides, in order | | --- | --- | --- | | the KB | ~/.local/share/rfc-kb | --out, then $RFC_KB_ROOT, then $XDG_DATA_HOME/rfc-kb | | fetched source | ~/.cache/rfc-extract | $RFC_CACHE_DIR, then $XDG_CACHE_HOME/rfc-extract |

Pass --out ./kb if you want a KB committed alongside a project instead.

Source is cached with conditional GETs, so re-runs are cheap and mostly offline. The cache is disposable; deleting it costs you one refetch.

Search

To find an RFC number when you don't know it:

rfc-extract search message signatures
9421  HTTP Message Signatures
      PROPOSED STANDARD, IETF, httpbis, February 2024
      This document describes a mechanism for creating, encoding, and verifying
      digital signatures or message authentication codes over components of an

1 of 1 results. Index confirmed 2026-08-03T09:14:22.104Z.

| Flag | Effect | | --- | --- | | --status <s> | filter by current status | | --stream <s> | filter by stream (IETF, IAB, IRTF, Independent, Legacy) | | --wg <w> | filter by working group acronym | | --since <year> | published in or after <year>, inclusive | | --until <year> | published in or before <year>, inclusive | | --current | drop RFCs that have been obsoleted | | --limit <n> | maximum hits to print, default 20 | | --refresh | ignore the HTTP cache | | --json | machine-readable result on stdout |

Search reads the RFC Editor's rfc-index.xml through the same cache as everything else, so it revalidates on every run and falls back to the copy on disk when you're offline. Matching is lexical: terms are weighted by whether they land in the title, keywords, authors or abstract, and every term has to match. It is not semantic, so "signing" won't find "signatures" and a query naming a concept will do worse than one naming words that appear in the title. Zero results exits 0.

API

One entry point, for rfc-mcp and anyone else who wants the pipeline in process:

import { extractRfc, type ExtractOptions, type RunSummary } from "rfc-extract";

const summary: RunSummary = await extractRfc("9421");

Without an out it writes to the same default the CLI uses. Pass one to put it elsewhere.

defaultKbRoot(), defaultCacheDir(), and expandTilde() are exported too, so a front end can resolve the same paths without duplicating the rules. Requirement and SourceTier are exported as types. Nothing else is public, and the exports map blocks deep imports.

What it extracts

Requirements are paragraph-scoped: one record per paragraph containing at least one BCP 14 keyword, not one per keyword. Sentence-splitting RFC prose is where these tools mangle quotes ("e.g.", "Section 2.1.", "[RFC8941]"), so a dense paragraph yields one record listing several keywords and no requirement is ever truncated. The RFC 2119/8174 boilerplate paragraph is excluded.

ABNF comes from sourcecode type="abnf" where it exists. Untyped artwork gets sniffed and marked as heuristic in a comment header, never merged as if it were authoritative. grammar.abnf is what the RFC defines, not a complete parseable grammar: RFC 9421 has one block because it imports the rest from RFC 8941.

Examples are every non-ABNF code block, one file each, extension from the declared type (http-message becomes .http, json becomes .json, untyped becomes .txt).

IANA is the IANA Considerations section with its tables pulled out, plus a link to the live registry. It's what the RFC asks for, not a registry fetch, and the file says so.

Errata come from the RFC Editor's full JSON dump, filtered by number, because there's no per-RFC endpoint. First fetch is chunky (around 11 MB) and then cached. Each entry keeps its status, since Verified and Rejected mean very different things. If the fetch fails, the run warns and continues, and errata.md says errata were unavailable rather than implying there are none.

IDs derive from the RFC's own paragraph numbers (pn="section-2.1-12" becomes req-2.1-12). Published RFCs are immutable, so the same input always produces the same ID, and the ID points at its own source.

Source tiers

Three tiers. meta.json and the generated README always record which one produced the KB.

| Tier | Source | Status | | --- | --- | --- | | rfcxml | /rfc/rfcNNNN.xml | full fidelity, preferred | | html-modern | rendered HTML with <section> and class="bcp14", roughly 2019 onward | near parity | | html-legacy | pre-2019 text inside <pre> | not supported, exits 1 |

Legacy RFCs are refused on purpose. That markup carries no section structure and no requirement markers, and a half-parsed 1999 RFC that looks confident is worse than a refusal. A .xml returning 404 isn't an error, it's the fallback to HTML.

Limitations

  • Pre-2019 RFCs aren't supported. RFC 2616 exits 1 and points you at the .txt.
  • Normative references are listed, not followed. Extracting a referenced RFC is a separate run.
  • Search is literal. There's no embedding or semantic index.
  • IANA output is what the RFC specifies, not the current state of the live registry.
  • Internet-Drafts and non-rfc-editor sources aren't handled.

Format

The emitted tree is documented in docs/kb-format.md. Unstable until 1.0.

Changelog

CHANGELOG.md, at the repo root, covers both packages.

License

MIT, for this code.

Not for what it emits. RFCs are copyrighted, and a knowledge base rearranges an RFC's text across a few hundred files, which makes it a derivative work rather than the full unmodified copy that the IETF Trust Legal Provisions plainly permit you to redistribute. Every emitted KB carries the source RFC's copyright notice in its README.md and meta.json. abnf/ and examples/ are code components under Section 4 of the TLP, licensed Revised BSD, and each of those directories gets a LICENSE.

Extracting an RFC to read it is not the case those terms restrict. Publishing the result is a different question, and this tool doesn't answer it for you.

rfc-extract is an independent tool. It is not affiliated with, endorsed by, or sponsored by the IETF, the IETF Trust, or the RFC Editor.