{"meta":{"title":"Publishing Node.js packages","intro":"In this tutorial, you'll learn how to publish Node.js packages to a registry as part of your continuous integration (CI) workflow.","product":"GitHub Actions","breadcrumbs":[{"href":"/en/actions","title":"GitHub Actions"},{"href":"/en/actions/tutorials","title":"Tutorials"},{"href":"/en/actions/tutorials/publish-packages","title":"Publish packages"},{"href":"/en/actions/tutorials/publish-packages/publish-nodejs-packages","title":"Publish Node.js packages"}],"documentType":"article"},"body":"# Publishing Node.js packages\n\nIn this tutorial, you'll learn how to publish Node.js packages to a registry as part of your continuous integration (CI) workflow.\n\n## Introduction\n\nThis guide shows you how to create a workflow that publishes Node.js packages to the GitHub Packages and npm registries after continuous integration (CI) tests pass.\n\n## Prerequisites\n\nWe recommend that you have a basic understanding of workflow configuration options and how to create a workflow file. For more information, see [Writing workflows](/en/actions/learn-github-actions).\n\nFor more information about creating a CI workflow for your Node.js project, see [Building and testing Node.js](/en/actions/automating-builds-and-tests/building-and-testing-nodejs).\n\nYou may also find it helpful to have a basic understanding of the following:\n\n* [Working with the npm registry](/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry)\n* [Store information in variables](/en/actions/learn-github-actions/variables)\n* [Using secrets in GitHub Actions](/en/actions/security-guides/using-secrets-in-github-actions)\n* [Use GITHUB\\_TOKEN for authentication in workflows](/en/actions/security-guides/automatic-token-authentication)\n\n## About package configuration\n\nThe `name` and `version` fields in the `package.json` file create a unique identifier that registries use to link your package to a registry. You can add a summary for the package listing page by including a `description` field in the `package.json` file. For more information, see [Creating a package.json file](https://docs.npmjs.com/creating-a-package-json-file) and [Creating Node.js modules](https://docs.npmjs.com/creating-node-js-modules) in the npm documentation.\n\nWhen a local `.npmrc` file exists and has a `registry` value specified, the `npm publish` command uses the registry configured in the `.npmrc` file. You can use the `setup-node` action to create a local `.npmrc` file on the runner that configures the default registry and scope. The `setup-node` action also accepts an authentication token as input, used to access private registries or publish node packages. For more information, see [`setup-node`](https://github.com/actions/setup-node/).\n\nYou can specify the Node.js version installed on the runner using the `setup-node` action.\n\nIf you add steps in your workflow to configure the `publishConfig` fields in your `package.json` file, you don't need to specify the registry-url using the `setup-node` action, but you will be limited to publishing the package to one registry. For more information, see [publishConfig](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#publishconfig) in the npm documentation.\n\n## Publishing packages to the npm registry\n\nYou can trigger a workflow to publish your package every time you publish a new release. The process in the following example is executed when the release event of type `published` is triggered. If the CI tests pass, the process uploads the package to the npm registry. For more information, see [Managing releases in a repository](/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release).\n\nTo perform authenticated operations against the npm registry in your workflow, you'll need to store your npm authentication token as a secret. For example, create a repository secret called `NPM_TOKEN`. For more information, see [Using secrets in GitHub Actions](/en/actions/security-guides/using-secrets-in-github-actions).\n\nBy default, npm uses the `name` field of the `package.json` file to determine the name of your published package. When publishing to a global namespace, you only need to include the package name. For example, you would publish a package named `my-package` to `https://www.npmjs.com/package/my-package`.\n\nIf you're publishing a package that includes a scope prefix, include the scope in the name of your `package.json` file. For example, if your npm scope prefix is \"octocat\" and the package name is \"hello-world\", the `name` in your `package.json` file should be `@octocat/hello-world`. If your npm package uses a scope prefix and the package is public, you need to use the option `npm publish --access public`. This is an option that npm requires to prevent someone from publishing a private package unintentionally.\n\nIf you would like to publish your package with provenance, include the `--provenance` flag with your `npm publish` command. This allows you to publicly and verifiably establish where and how your package was built, which increases supply chain security for people who consume your package. For more information, see [Generating provenance statements](https://docs.npmjs.com/generating-provenance-statements) in the npm documentation.\n\nThis example stores the `NPM_TOKEN` secret in the `NODE_AUTH_TOKEN` environment variable. When the `setup-node` action creates an `.npmrc` file, it references the token from the `NODE_AUTH_TOKEN` environment variable.\n\n```yaml copy\nname: Publish Package to npmjs\non:\n  release:\n    types: [published]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      id-token: write\n    steps:\n      - uses: actions/checkout@v6\n      # Setup .npmrc file to publish to npm\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://registry.npmjs.org'\n      - run: npm ci\n      - run: npm publish --provenance --access public\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n```\n\nIn the example above, the `setup-node` action creates an `.npmrc` file on the runner with the following contents:\n\n```shell\n//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}\nregistry=https://registry.npmjs.org/\nalways-auth=true\n```\n\nPlease note that you need to set the `registry-url` to `https://registry.npmjs.org/` in `setup-node` to properly configure your credentials.\n\n## Publishing packages to GitHub Packages\n\nYou can trigger a workflow to publish your package every time you publish a new release. The process in the following example is executed when the release event of type `published` is triggered. If the CI tests pass, the process uploads the package to GitHub Packages. For more information, see [Managing releases in a repository](/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release).\n\n### Configuring the destination repository\n\nLinking your package to GitHub Packages using the `repository` key is optional. If you choose not to provide the `repository` key in your `package.json` file, then your package will not be linked to a repository when it is published, but you can choose to connect the package to a repository later.\n\nIf you do provide the `repository` key in your `package.json` file, then the repository in that key is used as the destination npm registry for GitHub Packages. For example, publishing the below `package.json` results in a package named `my-package` published to the `octocat/my-other-repo` GitHub repository.\n\n```json\n{\n  \"name\": \"@octocat/my-package\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/octocat/my-other-repo.git\"\n  },\n}\n```\n\n### Authenticating to the destination repository\n\nTo perform authenticated operations against the GitHub Packages registry in your workflow, you can use the `GITHUB_TOKEN`. The `GITHUB_TOKEN` secret is set to an access token for the repository each time a job in a workflow begins. You should set the permissions for this access token in the workflow file to grant read access for the `contents` permission and write access for the `packages` permission. For more information, see [Use GITHUB\\_TOKEN for authentication in workflows](/en/actions/security-guides/automatic-token-authentication).\n\nIf you want to publish your package to a different repository, you must use a personal access token (classic) that has permission to write to packages in the destination repository. For more information, see [Managing your personal access tokens](/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) and [Using secrets in GitHub Actions](/en/actions/security-guides/using-secrets-in-github-actions).\n\n### Example workflow\n\nThis example stores the `GITHUB_TOKEN` secret in the `NODE_AUTH_TOKEN` environment variable. When the `setup-node` action creates an `.npmrc` file, it references the token from the `NODE_AUTH_TOKEN` environment variable.\n\n```yaml copy\nname: Publish package to GitHub Packages\non:\n  release:\n    types: [published]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n    steps:\n      - uses: actions/checkout@v6\n      # Setup .npmrc file to publish to GitHub Packages\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://npm.pkg.github.com'\n          # Defaults to the user or organization that owns the workflow file\n          scope: '@octocat'\n      - run: npm ci\n      - run: npm publish\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\nThe `setup-node` action creates an `.npmrc` file on the runner. When you use the `scope` input to the `setup-node` action, the `.npmrc` file includes the scope prefix. By default, the `setup-node` action sets the scope in the `.npmrc` file to the account that contains that workflow file.\n\n```shell\n//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}\n@octocat:registry=https://npm.pkg.github.com\nalways-auth=true\n```\n\n## Publishing packages using Yarn\n\nIf you use the Yarn package manager, you can install and publish packages using Yarn.\n\n```yaml copy\nname: Publish Package to npmjs\non:\n  release:\n    types: [published]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      # Setup .npmrc file to publish to npm\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://registry.npmjs.org'\n          # Defaults to the user or organization that owns the workflow file\n          scope: '@octocat'\n      - run: yarn\n      - run: yarn npm publish // for Yarn version 1, use `yarn publish` instead\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n```\n\nTo authenticate with the registry during publishing, ensure your authentication token is also defined in your `yarnrc.yml` file. For more information, see the [Settings](https://yarnpkg.com/configuration/yarnrc#npmAuthToken) article in the Yarn documentation."}