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

r2-postplan

v0.1.0

Published

Publish versioned HTML drafts to Cloudflare R2 and serve them through a Worker

Readme

r2-postplan

Publish one HTML draft to Cloudflare R2 and serve it through a tiny Worker. The stable URL always shows the latest publish, and every changed publish also gets a permanent version URL.

Requirements

  • Bun, or Node.js 22.18+
  • An existing R2 bucket
  • Bucket-scoped R2 credentials with object read and write access

Set credentials outside the project:

export R2_POSTPLAN_ACCESS_KEY_ID=...
export R2_POSTPLAN_SECRET_ACCESS_KEY=...

Temporary credentials may also set R2_POSTPLAN_SESSION_TOKEN. The CLI also accepts CLOUDFLARE_R2_ACCESS_KEY_ID and CLOUDFLARE_R2_SECRET_ACCESS_KEY, so the 1Password postplan Environment can be mounted directly at the project root as .env.

Worker

This repository is a Bun workspace: the npm CLI stays at the root and worker/ contains the postplan Worker.

Create the Worker environment file and set it to your existing R2 bucket, then deploy:

bun install
cp worker/.env.example worker/.env
# Edit worker/.env: CLOUDFLARE_R2_BUCKET=your-bucket
bun run worker:deploy

The 1Password postplan Environment can be mounted directly at worker/.env; its existing CLOUDFLARE_R2_BUCKET, account ID, and API token names work as-is.

Cloudflare assigns a URL shaped like https://postplan.<account-subdomain>.workers.dev. The Worker maps clean public paths to the existing R2 objects:

/<draft-id>     -> drafts/<draft-id>/index.html
/<draft-id>/v2  -> drafts/<draft-id>/v2/index.html

Setup

bunx r2-postplan setup ACCOUNT_ID BUCKET https://postplan.<account-subdomain>.workers.dev

Setup validates bucket access and stores only the account ID, bucket, S3 endpoint, Worker URL, and optional credential-file path. For a jurisdiction-specific or test endpoint, pass --endpoint URL. Pass --env-file /absolute/path/to/.env to remember a 1Password-mounted environment file. The path is stored in config; the secrets stay in 1Password.

Publish

bunx r2-postplan publish ./draft.html

Progress and the permanent version URL go to stderr. Only the stable URL goes to stdout, so it is safe to capture in scripts.

# Publish the same file as a separate draft
bunx r2-postplan publish ./draft.html --new

# Reconnect a local file to a remote draft
bunx r2-postplan publish ./draft.html --draft a1b2c3d4e5f6

# Skip the Worker-byte verification
bunx r2-postplan publish ./draft.html --no-wait

Only one regular .html file is uploaded. Use self-contained HTML or absolute asset URLs. The bucket can stay private; no public r2.dev URL is needed.

List and delete

bunx r2-postplan list
bunx r2-postplan delete

list always reads R2, so it works on a new machine and repairs stale or broken display cache. delete uses the same remote list; select drafts with the arrow keys and Space, then press Enter. Cancellation changes nothing.

Configuration lives under $XDG_CONFIG_HOME/r2-postplan (normally ~/.config/r2-postplan). R2 is the source of truth; local files are disposable cache, source-path mappings, and a short-lived journal used only to finish an interrupted publish without duplicating its permanent version.

The Worker exposes only draft pages and the short-lived object used by setup to verify access. This tool does not create buckets, upload assets, or configure custom domains.

Development

bun install
bun run check
bun test
bun run build

Before a release, set R2_POSTPLAN_LIVE_ACCOUNT_ID, R2_POSTPLAN_LIVE_BUCKET, and R2_POSTPLAN_LIVE_WORKER_URL alongside the credentials, then run bun run test:live. The opt-in check publishes two versions, measures Worker visibility, and cleans up its draft.

The npm package includes an agent skill at skills/r2-postplan/SKILL.md.