DEV Community

Sheng-Lin Yang
Sheng-Lin Yang

Posted on

Release my cli tool on npm

For my TypeScript CLI project using pnpm, I chose npm as the package registry and release tool.

  • Reason: npm is the standard package registry for Node.js and TypeScript projects, widely used and supported.
  • Link: npm repo for repo-snapshot

By releasing via npm, my CLI tool becomes easily installable by developers globally, either with npm or pnpm.

Before publishing, I made several changes to ensure the project would work smoothly:

  1. README.md – Updated installation instructions, usage examples, and added both npm and pnpm instructions.
  2. package.json
  • Added "main" field for entry point
  • Added "files" field to include only compiled files
  • Added "repository" information
    1. tsconfig.json – Adjusted output settings to generate proper compiled JavaScript for npm.

These changes made the project more user-friendly and compatible with npm’s publishing requirements.

Here is the detailed step-by-step process I followed:

Step 1 – Register npm Account

  • Created an account on npm
  • Verified my email

Step 2 – Prepare Git Repository

  • Pushed the latest code to GitHub
  • Used git tag to mark release versions, e.g., git tag v0.9.0 and git push --tags

Step 3 – Publish to npm

# Log in to npm
npm login

# Publish the package
npm publish --access public
Enter fullscreen mode Exit fullscreen mode

After this, my CLI tool was publicly available.

However, I wanted every new release to automatically publish to npm. I implemented CD using GitHub Actions:

Steps:

  1. Generate npm Access Token
  • npm Access Tokens

    1. Add Secret in GitHub
  • Repository → Settings → Secrets and variables → Actions → New Repository Secret

  • Name: NPM_TOKEN

  • Secret: Copy the npm token

    1. Create GitHub Actions Workflow
  • Path: .github/workflows/npm-publish.yml

  • Use example code from npm documentation

  • Customize branch, version, and other settings

Example snippet of workflow:

name: npm publish

on:
  push:
    tags:
      - 'v*.*.*'  # or 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
          registry-url: 'https://registry.npmjs.org'
      - run: npm ci
      - run: npm run build
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

This setup ensures that any new tag automatically triggers a release.

Even though I tested the installation myself, I wanted a fresh perspective:

  • I asked a partner unfamiliar with my project to follow the README instructions.
  • Observations:
  1. Initially, they missed the difference between npm and pnpm.
  2. They tried installing without nvm (required for npm but not for pnpm).
    • Fixes:
  • Clarified installation instructions in README
  • Added separate examples for npm and pnpm
  • Ensured users understand how to run the CLI immediately after install

This session was very useful to make the tool more beginner-friendly.

So the users can now install the tool globally:

Using npm:

npm install -g repo-snapshot
repo-snapshot --help
Enter fullscreen mode Exit fullscreen mode

Using pnpm:

pnpm add -g repo-snapshot
repo-snapshot --help
Enter fullscreen mode Exit fullscreen mode

Conclusion

Publishing repo-snapshot taught me:

  • How to prepare a TypeScript CLI for npm release
  • How to automate releases with GitHub Actions
  • How to test usability for external users
  • How to document clear installation instructions

Seeing my project live on npm and available for anyone to download was a rewarding experience and a major milestone for my CLI development journey.

Top comments (0)