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

commits-to-changelog

v2.1.0

Published

Create an unopionated CHANGELOG.md from Git commit history

Readme

commits-to-changelog

Create an unopionated CHANGELOG.md from Git commit history (see Details)

  • Rejects by default creating a Changelog if commits without associated Git tag exist, untagged commits can be allowed via setting requireTag
  • Creates CHANGELOG.md on each run from scratch, i.e. an existing on will be overwritten
  • Optionally writes defined number of lines from the start of CHANGELOG.md also to an existing section with heading "Changelog" (or "CHANGELOG" or any preferred case) in README.md (see linesToReadme under Settings)
  • Commits that are rather not relevant for users, e.g. "bump version" / changelog" / addressing "tests" (full list see filterDefaults under settings), are filtered out by default, further commits / commit types to filter out can be defined as as setting
    • I.e. no pressure to spoof commits or history to get a nice CHANGELOG
  • Special handling of Merged Branches
  • Does explicitly not do any magic based on things Conventional Commits to keep it compatible with less organized repos, but of course you should use commit conventions.

hh lohmann <[email protected]>

Changelog

Last 5 changes - see CHANGELOG file for full list and details

  • (2.1.0) README: Clarify: Git remote must be defined for current branch to be used
  • (2.1.0) Feature: Support multiple tags on the same commit
  • (2.0.1) README: Clarify: Git remote must be defined for current branch to be used
  • (2.0.0) Feature: Require tag (depending on setting requireTag): Reject creating a Changelog if commits without associated Git tag exist
  • (1.6.2) Feature: Write newest changelog entries also to README.md: add: Write HTML comment informing that content was inserted by commits-to-changelog

Synopsis

CLI without parameters

commits-to-changelog

Parameters

no parameters

Settings

Default settings can be overwritten by key-value pairs in an object as value for a key "commits-to-changelog" in a package.json belonging to the repo for which a CHANGELOG.md should be created, e.g.

// package.json
{
  "version": "...",
  "commits-to-changelog": {
    "headerDefault": "Latest",
    "headerMerged": "Implement",
    "linesToReadme": 5
  },
  "dependencies": {
    "...": "..."
  }
}

Possible Settings

filterCommits

Array of RegExp: Filter out commits / commit types identified by a message matching one of the RegExps in the array

  • Default: undefined
  • Cf. filterDefaults
  • May be used for types of commits identified by message patterns or exact commits to exclude from a sensible CHANGELOG
  • Since JSON has no own type for them, RegExps have to be defined as strings, unlike vanilla JavaScript filterCommits does handle e.g. ^exp$ exactly like /^exp$/ (i,e. interprets unquoted / at start and end as RegExp delimiters, not as literal / part of the RegExp)

filterDefaults

Boolean: Filter out commit types that are rather not relevant for users by matching commit messages against RegExps /^bump version$/i, /^changelog$/i, /^dev:/i, /^[Hh]ousekeeping/i, /^planning/i, /[Rr]efactoring/i, /tests/i

headerDefault

String to use as header for listing commits that do not belong to a defined Git tag

  • Default: "Current"

headerMerged

String to use as header for listing Merged Branches with a commit message of the form Merge branch '<branch name>'

  • Default: "Include (results of) separate branch"

linesToReadme

Write defined number of lines from the start of CHANGELOG.md also to an existing section with heading "Changelog" (or "CHANGELOG" or any preferred case) in README.md

  • Existing section content is overwritten
  • Short entry form with link to full CHANGELOG.md
  • If "0", false or undefined: Do not touch README.md (and a possibly existing section Changelog)
  • Default: "0"
  • Note: The value should be a positive integer, but for convenience also strings containing (only) a positive integer are accepted
  • Throws errors if greater "0" but no README.md or no section "Changelog" (case insensitive) was found in README.md

requireTag

Reject creating a Changelog if commits without associated Git tag exist

  • Boolean, default: true
  • Meant to improve workflows where a tag marks a release version and untagged commits would be missing when deploying via release version tag

Returns

no return

Examples

Sample CHANGELOG.md

See the CHANGELOG.md of this project

Sample for optionally writing to a section "Changelog" in README.md

See the section Changelog in this file (cf. details for optional setting linesToReadme under Settings)

Merged Branches

Branches that were merged as an explicit commit (i.e. no fast-forward) are listed as indented blocks with the message of the merge commit as a title line, e.g.

* dddb03a (HEAD -> master, origin/master) fix/unclear-error
|\
| * f6f8cd1 Update error message
|/
* 4bd8518 Update token hash to include encoded user name

as

- fix/unclear-error
  - Update error message
- Update token hash to include encoded user name

If the merge's commit message has the form Merge branch '<branch name>' it will be replaced by Include (results of) separate branch '<branch-name>', e.g.

* dddb03a (HEAD -> master, origin/master) Merge branch 'fix/unclear-error'
...

as

- Include (results of) separate branch 'fix/unclear-error'
...

Dependencies

none

Installation

CLIs should be installed systemwide ("global"). Strip off the -g parameter or replace it by a -D (as development dependency, -d for Bun) to explicitly restrict to a repo bounded usage.

Pick for your preferred package manager:

  npm i -g commits-to-changelog
  pnpm i -g commits-to-changelog
  bun i -g commits-to-changelog
  # For Yarn you should double check docs for your and / or
  # current Yarn version, newer versions do not treat `i package_name`
  # as an alias for `add ...` and exclude global installations
  yarn add commits-to-changelog

Details

The resulting CHANGELOG.md has the simple structure

# Changelog

## {groupheader} ({date})

- [{commit-subject}]({commit-link})
- [{commit-subject}]({commit-link})

## {groupheader} ({date})

- [{commit-subject}]({commit-link})
- [{commit-subject}]({commit-link})

(...)

where # Changelog is the title, a Markdown atx heading (i.e. using "#") of level 1 with the text "Changelog", followed by an empty line, and lists of commits that are grouped by

  • if setting requireTag is true (default): the Git tag they are associated with
  • if requireTag is false:
    • if given: a Git tag they are associated with
    • if no Git tag associated: an existing package.json version if this is a non-labeled SemVer and is newer than an existing previous tag that is also a non-labeled SemVer
    • if none of the above applies: the headerDefault (see Settings)

so that the applicable Git tag / package.json version or the headerDefault becomes the {groupheader} that together with the date of the Git tag or else the current date constitutes a Markdown heading of level 2 under which associated commits are listed as

  • if a Git remote for the current branch is given: a link [{commit-subject}]({commit-link}) formed by the subject of the commit and the remote entry for the commit what is usually a page including a Git diff for the commit
  • if no Git remote is given: the subject of the commit only

If multiple Git tags exist on the same commit (for whatever reason), then the {groupheader} will be a sorted list of all tags separated by /, e.g. commits like

b6f8f5c (tag: fix-that, tag: feat-this) Fix: ...this...
0c6ec5e Feature: ...that...

will appear in CHANGELOG.md as

## feat-this / fix-that (...date...)

- [Fix: ...that...](https://...)
- [Feature: ...this...](https://.../b6f8f5c)

Git tags may be lightweight or annotated, i.e. the type of a tag has no influence on the resulting CHANGELOG.md.

Besides the existence and characteristics of Git tags, a possible package.json and Git remote defintions the actually resulting CHANGELOG.md can be shaped by Settings.

Source Code

Prior Work

The (initial) code here is forked from git-to-changelog, an already very good solution, but due to a hardwired search path '../../package.json' - mimicking npm's way of structuring a node_modules folder - not usable with pnpm, and while fixing this some other little things were changed / improved (see CHANGELOG) and made the initial little fix grow into an own project

License

References

CommonMark Spec: ATX headings

Conventional Commits

Git commmit subject

Git: diff

Git: lightweight vs. annotated tags

Git: Working with Remotes: Showing Your Remotes

git-to-changelog

Non-labeled SemVer