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

@jfrader/changelog

v1.4.0

Published

Zero-dependency changelog system: markdown entries, an agent-facing MD workflow, a build that emits CHANGELOG.md + JSON, and a self-contained end-user page served by a tiny backend.

Readme

@jfrader/changelog

npm version npm downloads ci license node

A zero-dependency changelog system for any project. It combines:

  1. Markdown entries — one file per end-user-visible change, reviewed in git.
  2. An agent-facing MD workflow — SKILL.md, RUNBOOK.md and an AGENTS.md snippet that keep coding agents recording changes as they ship.
  3. A build — turns entries into CHANGELOG.md (human doc), changelog.json (feed), and index.html (a self-contained end-user page).
  4. A tiny backend — changelog serve serves the page, the JSON feed and a read-only API with zero runtime dependencies.
  5. A browser-safe SDK — @jfrader/changelog/sdk powers in-app "What's New" modals in any framework, with seen-tracking and filtering.

Quick start

npm install -D @jfrader/changelog

# 1. Init once per repository:
npx changelog init --product myapp --name "My App" \
  --tagline "What is new" --accent "#22c55e"

# 2. Append changelog/AGENTS.snippet.md to your AGENTS.md (optional, for agents).

# 3. Record a change:
npx changelog add --title "Dark mode" --kind feature --tags ui

# 4. Build before shipping:
npx changelog build

# 5. Preview / publish:
npx changelog serve --port 4567

The CLI walks up from the current directory to find changelog/, so you can run it from anywhere inside the repository.

Registry choice

npmjs is the zero-configuration default. GitHub Packages carries the same verified tarball, but GitHub requires authentication even for public npm packages:

@jfrader:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}

Registry selection applies to the whole @jfrader scope; npm does not fall back from GitHub Packages to npmjs. Projects that map that scope to GitHub must authenticate there or use an explicit npmjs tarball URL for a package that is not mirrored.

Entry format

Each entry is changelog/entries/YYYY-MM-DD--short-slug.md:

---
kind: feature            # feature | improvement | fix | breaking | chore
date: 2026-08-07
title: "What changed"
tags: [match, replay]
audience: all            # all | player | manager | guest | admin
version: 0.1.0           # optional
published: true          # false = draft, excluded from builds
---

# What changed

One to three short, literal sentences for end users.

Required: kind, date and a title. Invalid entries are reported and skipped by the build. Drafts (published: false) never reach the page.

Audiences

Set audiences in changelog/config.json to use your product's roles:

{
  "audiences": ["all", "trainer", "client"]
}

Then use audience: trainer in an entry or changelog add --audience trainer. Without audiences, the defaults remain all, player, manager, guest, and admin. all is always accepted, even when omitted from the configured list, and is the default for new entries. Unknown values produce a warning naming the configured list and fall back to all, both when parsing entries and when scaffolding them with add. The built JSON preserves accepted audience values unchanged.

Commands

| Command | Purpose | | --- | --- | | changelog init | Scaffold changelog/ (config, entries, docs). --force re-creates config + docs. | | changelog add | Scaffold a new entry. Flags: --title (required), --kind, --date, --version, --tags, --audience, --draft, --body, --root. | | changelog list | List entries (--all includes drafts). | | changelog build | Generate CHANGELOG.md, changelog.json, index.html. | | changelog serve | Serve the page + JSON + API. Flags: --port, --host, --root. |

End-user page

changelog build writes changelog/index.html, a self-contained page that embeds its own CSS, JS and the full JSON data — it works from file:// too. It includes:

  • a "What's new" hero with per-kind summary chips;
  • filter chips (All / new features / improvements / fixes / breaking changes);
  • search, a "New" pulse on the latest feature, and a dark/light theme toggle;
  • an optional link back to the product, set with homeUrl in changelog/config.json (for example "/" or a full URL);
  • a safe mini-Markdown renderer for entry bodies.

Use /changelog as the public URL. On static SPA hosts, add an exact internal rewrite from /changelog to /changelog/index.html before the SPA catch-all; the built-in server already serves the page at both paths. An internal rewrite keeps the clean URL visible instead of redirecting visitors to the file name.

Backend

changelog serve is a zero-dependency node:http server:

| Route | Content | | --- | --- | | / | the end-user page | | /changelog.json | machine-readable feed | | /api/entries | JSON API (same feed) | | /api/health | health probe | | /entries/<file>.md | raw published-entry markdown (read-only) |

It is read-only by design: entries change in git, get built, then get served.

In-app "What's New" modal (SDK)

Import the browser-safe SDK from any web app:

import {
  computeWhatsNewFromStorage,
  markWhatsNewSeen,
} from "@jfrader/changelog/sdk";
import changelogData from "./changelog.json"; // from `changelog build`

const { entries, hasNew } = computeWhatsNewFromStorage(
  changelogData.entries,
  () => window.localStorage,
);

// When the player dismisses the modal:
markWhatsNewSeen(() => window.localStorage, entries);

The SDK has no Node or DOM dependencies — only a tiny storage interface — so it works in React, Vue, Svelte, or vanilla JS. The storage-backed helpers keep separate same-day releases visible and tolerate unavailable browser storage. In SSR apps, call them after the component mounts. You render the modal shell in your own UI and design tokens.

Examples

See examples/ for a runnable vanilla "What's New" modal (open the HTML in a browser, no build step) and a React reference component, both driven by the SDK.

Agent MD system

Each initialized project gets:

  • changelog/SKILL.md — a skill agents can reference for changelog maintenance.
  • changelog/RUNBOOK.md — the full runbook (format, workflow, deploy, FAQ).
  • changelog/AGENTS.snippet.md — append to the repo AGENTS.md so every agent keeps entries current while it works (already appended in all three repos).

Development

npm install
npm run check     # typecheck + tests + build
npm test          # node test runner (tsx)
npm run build     # tsc -> dist

Publishing

Push an annotated v<package-version> tag from main. The release workflow checks the tag and lockfile, builds and tests once, packs one immutable tarball, then verifies or publishes that exact artifact to npmjs and GitHub Packages. Retries are safe: an existing matching artifact is accepted, while a different artifact at the same version fails the release.

The npmjs package uses a trusted publisher for jfrader/changelog → .github/workflows/publish.yml; GitHub Packages uses the workflow's scoped GITHUB_TOKEN.

GitHub creates a personal package as private on its first publication. After the first workflow succeeds, make it public once from the package's Package settings → Danger Zone → Change visibility. Later versions keep that setting.

The CLI entry is dist/cli.js; the public API is exported from dist/index.js so CI and in-app "What's new" panels can reuse the same parsing and build logic.

Layout

src/
  cli.ts              # CLI entry
  index.ts            # public API
  core/
    types.ts          # shared types
    frontmatter.ts    # dependency-free frontmatter parse/serialize
    entry.ts          # entry parsing, validation, naming
    project.ts        # changelog root discovery + config
    build.ts          # aggregation + output writing
    render-md.ts      # CHANGELOG.md renderer
    commands.ts       # init/add/list/build/serve
    templates.ts      # entry, runbook, skill, AGENTS snippet templates
  ui/page.ts          # self-contained end-user page renderer
  server/server.ts    # tiny static + API backend
test/                 # node test runner specs