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

rapier-html

v1.1.89

Published

One command turns a Markdown file into one offline HTML file: the whole Rapier editor with the document inside. Opens in any browser, phone or desktop, with no install or account. Write, draw and paint watercolor, then Send back the edits to your AI agent

Readme

rapier-html

Give a person a document they can read, edit and keep: one command writes one HTML file that is the whole editor, offline, with the document inside.

Use it for a plan to rearrange, an illustrated guide to annotate, a draft to continue writing, or a revision to review. Text and drawings stay editable, and the file remains usable independently of a hosted workspace.

  • The page writes, draws and paints, saves Markdown, exports Word, PDF and a web page, and prints, with no account and nothing fetched to open, edit or save.
  • --return adds a one-use Send back address from the agent door: the person edits offline, presses Send back, and the agent reads the returned copy.
  • --view draw opens on Draw; --propose original.md opens on the diff of a proposed change, and the person keeps or drops each change; --by <name> says on that diff who proposed it and when.
  • wrap and unwrap carry a document into a page and out again, exactly, for programs.

Node 22 or newer.

npx -- [email protected] notes.md                          # the editor, notes.md inside it, written beside the file
npx -- [email protected] notes.md --view draw              # opens on Draw: sketch and paint, the document behind it
npx -- [email protected] notes.md --view notes             # opens the Notes library
npx -- [email protected] notes.md --drawing sketch.svg     # carries a drawing, opened on Draw over the document
npx -- [email protected] --propose original.md proposal.md # opens on the diff of a proposed change
npx -- [email protected] notes.md --return "$RETURN_URL" --return-expires-at "$RETURN_EXPIRES_AT" # Send back
npx -- [email protected] notes.md out.html                 # a named output
npm install [email protected]                              # as a library: wrap, unwrap

The first -- is for npm, so --help reaches the command. It never overwrites a file.

For live shared editing, open the document through Rapier's MCP tools. Read the person's current text or drawing before revising it, show the attributed changes, and export Markdown or an offline editor when the result needs an independent copy. Send back returns an edited offline copy for inspection and review alongside the hosted document.

Will markers in the Markdown control agent edits: keep, append, edit.

Send an edited document back

Call document.create_return on the Rapier agent door for the document's workspace and pass its return_url and return_expires_at as --return "$RETURN_URL" --return-expires-at "$RETURN_EXPIRES_AT", or wrap(..., {return: return_url, return_expires_at}). Only the worker's HTTPS return route at https://mcp.rapier.website/return/… is accepted. The page then shows Send back in Share; a page without an address has no such action.

The person edits offline and presses Send back: the current source and filename go once, the page shows the acceptance or the worker's refusal, and it sends nothing again. The return lasts up to one day, takes one document up to 25 MiB and grants no access to the agent's workspace. After the expiry, or a refusal, Share offers Save instead; bring that file back to the assistant for a fresh return.

The agent's document.wait_for_user returns a returned receipt with the return_id, name and time; document.get_context lists receipts; document.read_context({return_id, start: 0}) reads the source, continuing at the returned end until complete. The returned copy stays separate from the workspace's current document.

As a library

Save this as example.mjs in the folder you installed into and run node example.mjs:

import {readFile, writeFile} from 'node:fs/promises';
import {wrap, unwrap} from 'rapier-html';

const rapier = await readFile(new URL('./rapier.html', import.meta.resolve('rapier-html')), 'utf8');
const words = '# Hello\r\n\r\nA note about </script> and C:\\Users\\me.\n';
const page = wrap(rapier, words, 'hello.md', {view: 'draw'});   // opens on Draw, the note behind it
console.log('words back exactly:', unwrap(page).text === words);
await writeFile('hello.rapier.html', page, {flag: 'wx'});        // 'wx': never over an existing file

wrap(rapierHtml, text, name, {view, drawing, drawingName, base, baseName, return: returnURL, return_expires_at}) and unwrap(pageHtml), which returns the same fields with null for what a page does not carry. Also exported: encodeCarried, decodeCarried, main.

How the page carries the document

One <script type="text/markdown" id="rapier-document"> block at the top of the body, never executed, read once at boot. A drawing rides in id="rapier-drawing", the text a change was proposed against in id="rapier-base", the view to open on in the document block's data-view, the optional return URL in data-return and its exact expiry in data-return-expires-at. The block holds no < before / or !, no carriage return and no NUL: \\, \/, \!, \r and \0 stand for them, one reversible pass each way, so a note about HTML is as safe as any other. A byte-order mark is kept as a fact of the file and written back on Save.

Safety

  • It never overwrites: an existing output, the document itself included, is refused, as are unknown options, a --view other than draw or notes, a --drawing or --propose with no file, a return without its expiry, an invalid expiry, an unsafe return URL and a third filename.
  • Nothing reports on the page's use. It reaches the network only when the document or the person asks: a linked picture or video, a plug-in on first use (maths, diagrams, PDF import, text in pictures, a letter set), or Send back. A return URL names only the worker's exact origin and route; credentials, query strings and fragments are refused.

Optional edit history

wrap(page, text, filename, {ledger, authorship}) accepts the public kit's rapier-ledger/1 and rapier-authorship/1 objects. unwrap(page) returns the checked parts beside its text. Neither is on by default. An authorship projection contains only attribution of current characters; a full ledger contains deleted text too. A wrong-text, malformed, duplicate or inconsistent part throws instead of attaching false history. Saved Markdown written with the kit's ledger/carried.writeDocument is read automatically when wrapping. Rewrapping a page without parts drops its previous document's parts. Published npm files carry their own staged MIT validator closure; no source checkout is needed.

Licence

AGPL-3.0-only (LICENSE): the page is the Rapier editor with the notices of the libraries it carries. The Markdown standard without the editor is rapier-markdown-kit (MIT). Rapier is https://rapier.website. BUILD.json records the page's size, SHA-256, build time and Node version.