gh-release-assets

June 18, 2026 ยท View on GitHub

paperclip

gh-release-assets

Upload assets to a GitHub release.

npm build downloads

Features

  • Upload one or more assets to an existing GitHub release.
  • Emits upload-asset, upload-progress, and uploaded-asset events, with progress details (percentage, bytes transferred, ETA, and more).
  • Authenticates with a GitHub token.
  • Usable as a library or as a command-line tool.

Based on the awesome work of @remixz as part of publish-release.

Install

npm install gh-release-assets

Usage

This package is ESM-only and ships TypeScript types. Import it with either the named or default export:

import { uploadAssets } from 'gh-release-assets'
// or: import uploadAssets from 'gh-release-assets'

Pass in the upload url and an array of local files you'd like to upload. If you want to specify a new name for the file once it is uploaded, use an object with name and path keys.

import { uploadAssets } from 'gh-release-assets'

uploadAssets({
  url: 'https://uploads.github.com/repos/octocat/Hello-World/releases/1197692/assets{?name}',
  token: process.env.GITHUB_TOKEN,
  assets: [
    '/path/to/foo.txt',
    '/path/to/bar.zip',
    {
      name: 'baz.txt',
      path: '/path/to/baz.txt'
    }
  ]
}, function (err, assets) {
  console.log(assets)
})

Keep your token in an environment variable rather than hardcoding it in a release script.

GitHub returns the upload url in the correct format after you create a release as upload_url. You can also get the upload url from the releases endpoint like:

curl -i https://api.github.com/repos/:owner/:repo/releases

A token is required.

Events

uploadAssets returns an EventEmitter and emits the following events:

  • upload-asset - (name) - Emits before an asset file starts uploading. Emits the name of the file.
  • upload-progress - (name, progress) - Emits while a file is uploading. Emits the name of the file and a progress object (UploadProgress).
  • uploaded-asset - (name) - Emits after an asset file is successfully uploaded. Emits the name of the file.

The progress object has these fields (all numbers), exported as the UploadProgress type:

interface UploadProgress {
  /** Fraction complete, 0โ€“100. */
  percentage: number
  /** Bytes transferred so far. */
  transferred: number
  /** Total bytes to transfer. */
  length: number
  /** Bytes remaining. */
  remaining: number
  /** Estimated seconds remaining. */
  eta: number
  /** Seconds elapsed. */
  runtime: number
  /** Bytes since the previous progress event. */
  delta: number
  /** Bytes per second. */
  speed: number
}

CLI

Installing the package provides a gh-release-assets command.

gh-release-assets --url <upload_url> [asset...]

Pass the release upload URL with --url and one or more file paths as positional arguments. Authentication uses the --token flag, or the GITHUB_TOKEN environment variable when the flag is absent.

gh-release-assets --url 'https://uploads.github.com/repos/octocat/Hello-World/releases/1197692/assets{?name}' --token "$GITHUB_TOKEN" ./dist/foo.zip ./dist/bar.txt

Run it without installing using npx:

npx gh-release-assets --url <upload_url> ./foo.zip

Uploaded filenames are printed to stdout; progress is written to stderr. The command exits non-zero on error, or when --url, an asset, or a token is missing. Use -h / --help for usage.

Contributing

Contributions welcome! Please read the contributing guidelines before opening an issue or making a pull request.

License

ISC

Logo is the paperclip emoji, rendered locally from the system Apple Color Emoji font.