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

@plugdash/autobuild

v0.2.0

Published

Fires a Cloudflare Pages, Netlify, or Vercel build hook on every publish from EmDash

Readme

@plugdash/autobuild

Publish in admin, live in 60 seconds. Triggers a Cloudflare Pages, Netlify, or Vercel build hook every time you publish content in EmDash. One config line, one env var, done. Only on EmDash - this is the plugin that makes a headless CMS feel live.

Install

pnpm add @plugdash/autobuild

Register

// astro.config.mjs
import { defineConfig } from "astro/config";
import emdash from "emdash";
import { autobuildPlugin } from "@plugdash/autobuild";

export default defineConfig({
  integrations: [
    emdash({
      plugins: [
        autobuildPlugin({
          hookUrl: import.meta.env.CF_PAGES_DEPLOY_HOOK,
          collections: ["posts"],
          debounceMs: 5000,
        }),
      ],
    }),
  ],
});

Store the hook URL as an environment variable. Never commit it.

Getting a deploy hook URL

  • Cloudflare Pages: Project -> Settings -> Builds & deployments -> Deploy hooks. Creates a URL like https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/...
  • Netlify: Site settings -> Build & deploy -> Build hooks. Creates a URL like https://api.netlify.com/build_hooks/...
  • Vercel: Project Settings -> Git -> Deploy Hooks. Creates a URL like https://api.vercel.com/v1/integrations/deploy/...

Configuration

Admin dashboard

After installing, open the EmDash admin and go to Plugins - Autobuild - Settings. Hook URL, method, debounce window, and collections are available there. The current hook URL is shown masked (hostname + first 8 chars of path); leave the field blank on save to keep the existing value.

Config options

| Option | Type | Default | Description | | -------------- | -------------------------- | --------------- | --------------------------------------------------------- | | hookUrl | string | required | Deploy webhook URL. Must be https. Must not be localhost or a private IP | | method | "POST" \| "GET" | "POST" | HTTP method. Vercel uses POST, Cloudflare Pages uses POST, Netlify uses POST or GET | | collections | string[] | all collections | Only trigger rebuilds for these collections | | statuses | ContentStatus[] | ["published"] | Statuses that trigger a rebuild | | debounceMs | number | 5000 | Coalesce rapid publishes into one deploy | | timeout | number | 5000 | Request timeout in milliseconds | | body | Record<string, unknown> | none | Optional JSON body. Most deploy hooks accept empty POST | | headers | Record<string, string> | none | Optional additional request headers | | allowedHosts | string[] | auto | Override the auto-parsed allowedHosts (for CDN/LB setups) |

How it works

  1. Plugin registers on content:afterSave and content:afterDelete with read:content and network:fetch capabilities.
  2. When a published post is saved (or any post is deleted), the plugin schedules a debounced webhook fire.
  3. After the debounce window elapses, it POSTs to the hook URL via ctx.http.fetch().
  4. The original save/delete event is never blocked - webhook failures log but do not fail the admin operation.

Security

autobuild validates the hook URL before every fetch:

  • https:// only. No http, no file, no other schemes.
  • Blocks localhost, 127.x.x.x, 0.0.0.0, ::1.
  • Blocks RFC1918 private ranges: 10.x.x.x, 172.16-31.x.x, 192.168.x.x.
  • Blocks 169.254.x.x (link-local, including the AWS instance metadata endpoint).

A misconfigured hookUrl fails closed: no fetch is made, an error is logged.

What it does not do

  • Does not retry failed deploys. The next publish retries.
  • Does not verify that the deploy succeeded - check your Pages/Netlify/Vercel dashboard for deploy status.
  • Does not sign or authenticate requests. Deploy hooks are already secret URLs.
  • Does not persist debounce state across process restarts. A pending webhook is dropped on restart.
  • Does not ship a UI component. This plugin is pure infrastructure.