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

gh-release

v8.1.0

Published

Create a GitHub Release for a Node package

Readme

gh-release

Create a GitHub Release for a Node package.

npm build downloads

Features

  • Creates a GitHub release via the Releases API.
  • Defaults to information from package.json and CHANGELOG.md.
  • Uploads release assets.
  • Works as a CLI tool or programmatically.

Install

npm install gh-release

Usage

This package is ESM-only and ships TypeScript types. It requires Node 22.12 or newer.

Run it at the root of the project to be released. It expects a package.json (and optionally a CHANGELOG.md) in the working directory, and prints the release URL to stdout on success.

Authentication

Authentication is token-only. gh-release resolves a GitHub token in this order:

  1. the --token flag,
  2. the GH_RELEASE_GITHUB_API_TOKEN environment variable,
  3. the GITHUB_TOKEN environment variable.

If none is set it exits with an error. The token needs the repo scope. If you use the GitHub CLI (gh), its gh auth token command prints a token for the account you are signed in as, which is a convenient way to provide one locally:

export GH_RELEASE_GITHUB_API_TOKEN=$(gh auth token)

Command-line interface

$ gh-release

creating release v1.0.9 for ungoldman/gh-release-test

name:               v1.0.9
tag_name:           v1.0.9
target_commitish:   3b06705e43be83363f063966f36ede3990a2842a
endpoint:           https://api.github.com
body:

### Maintenance
* test: testing latest CLI output
* deps: gh-release@8

publish release to github? (Y/n)
https://github.com/ungoldman/gh-release-test/releases/tag/v1.0.9

Get usage info with --help or -h:

$ gh-release --help
Usage: gh-release [options]

Create a GitHub Release for a Node package.

Options:
  -t, --tag_name <tag>          tag for this release
      --tag-prefix <prefix>     prefix for the derived tag and title (default "v")
  -c, --target_commitish <ref>  commitish value for tag
  -n, --name <name>             text of release title
  -b, --body <body>             text of release body
  -o, --owner <owner>           repo owner
  -r, --repo <repo>             repo name
  -d, --draft                   publish as draft
  -p, --prerelease              publish as prerelease
  -w, --workpath <path>         path to working directory
  -e, --endpoint <url>          GitHub API endpoint URL
  -a, --assets <list>           comma-delimited list of assets to upload
      --dry-run                 dry run (stops before release step)
      --generate-notes          let GitHub generate the release notes
      --token <token>           GitHub token (defaults to $GH_RELEASE_GITHUB_API_TOKEN or $GITHUB_TOKEN)
  -y, --yes                     bypass confirmation prompt for release
  -h, --help                    show help
  -v, --version                 show version number

Node API

Import the named ghRelease export. The default export remains available for backwards compatibility.

import { ghRelease } from 'gh-release'
// backwards-compatible alternative: import ghRelease from 'gh-release'

// all options except auth have defaults and can be omitted
const options = {
  tag_name: 'v1.0.0',
  target_commitish: 'main',
  name: 'v1.0.0',
  body: '* init\n',
  draft: false,
  prerelease: false,
  repo: 'gh-release',
  owner: 'ungoldman',
  endpoint: 'https://api.github.com', // for GitHub Enterprise, use http(s)://hostname/api/v3
  // auth is required and must be a token
  auth: { token: process.env.GH_RELEASE_GITHUB_API_TOKEN }
}

const release = ghRelease(options, (err, result) => {
  if (err) throw err
  console.log(result.html_url)
})

// when uploading assets, the returned EventEmitter relays progress
release.on('upload-asset', (name) => {})
release.on('upload-progress', (name, progress) => {})
release.on('uploaded-asset', (name) => {})

Defaults

All default values are taken from package.json unless specified otherwise.

| name | description | default | | ---: | ----------- | ------- | | tag_name | release tag | tag prefix + version | | target_commitish | commitish value to tag | HEAD of current branch | | name | release title | tag prefix + version | | body | release text | CHANGELOG.md section matching version (empty if no changelog) | | owner | repo owner | repo owner in repository | | repo | repo name | repo name in repository | | draft | publish as draft | false | | prerelease | publish as prerelease | false | | assets | release assets to upload | false | | endpoint | GitHub API endpoint URL | https://api.github.com |

Override defaults with flags (CLI) or the options object (Node).

The tag and title are the version prefixed with v. Change the prefix with --tag-prefix <prefix> (CLI) or tagPrefix (Node), and pass an empty string to drop it (so the tag is the bare version). Override the tag or title outright with --tag_name/--name.

gh-release --tag-prefix ''               # 1.2.3 instead of v1.2.3
gh-release --tag-prefix 'service/env/'   # service/env/1.2.3, for scoped or monorepo tags

Git allows slashes in tag names, so a prefix like service/env/ produces the tag service/env/1.2.3. The title takes the same value, so pair it with --name if you want a cleaner one.

CHANGELOG.md is optional. Without it, gh-release tags from the package.json version with an empty body. When it is present, the matching section is used, and that section may itself be empty. Either way the CLI prints a warning when the body ends up empty.

To fill the body without a changelog, pass --generate-notes (CLI) or set generate_release_notes: true (Node). This enables GitHub's automatically generated release notes, which GitHub builds server-side from the merged pull requests and commits since the previous release. The option name matches the GitHub API field it sets.

Standards

Motivation

There are packages that already do something like this, and they're great, but I want something that does this one thing really well and nothing else, leans heavily on standards in package.json and CHANGELOG.md, and works both as a CLI tool and programmatically in Node.

Contributing

Contributions welcome! Please read the contributing guidelines first.

History

Please read the change log for a human-readable history of changes.

Tests

gh-release uses Biome for linting and formatting and Node's built-in test runner. Run everything with npm test, and check coverage with npm run coverage.

See also

License

ISC

Rocket image is from emojipedia.