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

@bestikk/changelog

v1.0.2

Published

Manage a Keep a Changelog changelog (AsciiDoc or Markdown): roll the Unreleased section into a dated release, and extract a release as Markdown release notes.

Readme

bestikk-changelog

Manage a Keep a Changelog style changelog, in AsciiDoc or Markdown: roll the "Unreleased" section into a dated release, and extract a release section as Markdown release notes suitable for a GitHub release.

Changelog formats

Two formats are supported, selected with the format option (adoc or markdown, default adoc) — the CLI infers it from the --file extension (.md/.markdown -> markdown, otherwise adoc).

adoc (AsciiDoc, e.g. CHANGELOG.adoc)

Converted to Markdown via downdoc, an optional dependency (see Optional downdoc dependency).

Headings use the same style presets as the markdown format below (default title-paren), just with the AsciiDoc == marker instead of Markdown’s level 2 marker — both are a "level 2" heading in their respective syntax.

= Project Changelog

== Unreleased

== v1.0.0 (2024-01-15)

Optional summary paragraph, used as the release notes summary.

=== Added

* A new feature

=== Fixed

* A bug fix

== v0.9.0 (2023-12-01)
...

markdown (native Markdown, e.g. CHANGELOG.md)

Used as-is, no conversion needed. The exact heading syntax is configurable via the style option (a preset name or a custom style object — see lib/heading-styles.js), since projects tend to spell the "Unreleased"/release headings slightly differently. Category sections (e.g. "Added", "Fixed", shown as a plain level 3 heading below) always use the same syntax, whatever the style.

  • keepachangelog (default)
    Canonical Keep a Changelog syntax.

    ## [Unreleased]
    ## [<version>] - <date>
  • title-paren
    e.g. asciidoctor-emoji.

    ## Unreleased
    ## v<version> (<date>)
  • title-paren-suffix
    e.g. asciidoctor-vscode, whose release heading also allows an optional "(qualifier)" and a free-form "- suffix" (only the latter is written back, via the "suffix" option).

    ## Unreleased
    ## <version> [(qualifier)] (<date>) [- suffix]
# Project Changelog

## [Unreleased]

## [1.0.0] - 2024-01-15

Optional summary paragraph, used as the release notes summary.

### Added

- A new feature

### Fixed

- A bug fix

## [0.9.0] - 2023-12-01
...

A convention that doesn’t fit any preset can be passed directly as a custom style object instead of a preset name:

const style = {
  unreleasedHeading: '## TBD',
  releaseHeadingTemplate: (version, date) => `## Release ${version} — ${date}`,
  releaseHeadingRegex: (escapedVersion) =>
    new RegExp(`(?:^|\\n)## Release ${escapedVersion} — ([^\\n]+)\\n([\\s\\S]*?)(?=\\n## |$)`),
}

rollUnreleased(content, '1.0.0', '2024-01-15', { format: 'markdown', style })

Install

npm install @bestikk/changelog

Optional downdoc dependency

downdoc is listed as an optionalDependencies and only loaded when processing the adoc format, so a project that only uses a Markdown changelog doesn’t need it. It is installed by default by npm/npx/pnpm/yarn; if it’s missing (e.g. installed with --omit=optional) and the adoc format is used, an explicit error tells you to install it.

CLI usage

# Roll the "Unreleased" section into a dated "v1.0.0" section
npx bestikk-changelog release 1.0.0

# Print the "v1.0.0" section as Markdown release notes (for a GitHub release)
npx bestikk-changelog notes 1.0.0

# Same, for a Markdown changelog (format inferred from the .md extension)
npx bestikk-changelog release 1.0.0 --file CHANGELOG.md
npx bestikk-changelog notes 1.0.0 --file CHANGELOG.md

Both commands accept --file <path> (default: CHANGELOG.adoc), --format <adoc|markdown> (default: inferred from --file), and --style <name> (default keepachangelog for markdown, title-paren for adoc; see the styles above). release accepts --date <YYYY-MM-DD> (default: today) and --suffix <text> (appended to the release heading, used by the title-paren-suffix style, e.g. --suffix "- @octocat"). notes accepts --author <name> (default: $GITHUB_ACTOR or the tag’s commit author), --previous-tag <tag> (default: the tag before v<version>), and --repo-url <url> (default: inferred from the origin git remote) — used to link the full diff between releases.

Library usage

import { rollUnreleased, extractReleaseNotes } from '@bestikk/changelog'
import { readFileSync, writeFileSync } from 'node:fs'

const content = readFileSync('CHANGELOG.adoc', 'utf8')

// Roll "Unreleased" into "v1.0.0 (2024-01-15)" (format defaults to "adoc")
writeFileSync('CHANGELOG.adoc', rollUnreleased(content, '1.0.0', '2024-01-15'))

// Extract "v1.0.0" as Markdown release notes
const notes = await extractReleaseNotes(content, '1.0.0', {
  author: 'octocat',
  previousTag: 'v0.9.0',
  repoUrl: 'https://github.com/example/example',
})

Pass { format: 'markdown' } as the last argument to work with a native Markdown file instead, and { format: 'markdown', style: 'title-paren' } (or another preset, or a custom style object) to match its heading syntax.

License

MIT