Publishing Your Own Package

Should you publish?

Once you've written something reusable — a helper library, a CLI tool, a component — you can publish it to the npm registry so anyone can npm install it (and so you can reuse it across your own projects). Everything in this chapter is optional; most people use npm for years without ever publishing. But it's surprisingly quick.

1. Get an account and log in

Create a free account at npmjs.com, then connect your terminal to it:

Log the terminal into npm

Terminal
$ npm login
$ npm whoami   # confirms who you're logged in as
In VS Code
  1. Open the terminal (Ctrl + backtick)
  2. Run npm login — it opens a browser to authenticate
  3. npm whoami should print your username

Enabling two-factor authentication on your npm account is strongly recommended, especially before publishing.

2. The package.json fields that matter for publishing

A private project can be loose about package.json; a published one can't, because these fields become public and define what people get:

{
  "name": "my-cool-tool",        // must be unique on npm (or scoped, below)
  "version": "1.0.0",            // every publish needs a new version
  "description": "...",          // shown in search results
  "main": "index.js",            // the entry file people import
  "files": ["dist", "index.js"], // allowlist of what to include
  "license": "MIT",              // how others may use it
  "keywords": ["cli", "tool"]    // help people find it
}
  • name + version — together they identify exactly one release. You can never republish the same version twice.
  • main (or the newer exports) — the file loaded when someone writes import x from 'my-cool-tool'.
  • files — an allowlist of what goes in the package. This is the safe way to avoid shipping junk; the alternative is a .npmignore blocklist, but an allowlist is harder to get wrong.

3. Scoped packages (the easy way to get a free name)

Good short names are mostly taken. A scoped name lives under your username, like @yourname/my-cool-tool, so it's always available. Scoped packages are private by default, so you publish them as public explicitly (free):

Publish a scoped package publicly

Terminal
$ npm publish --access public
In VS Code
  1. Set your package name to @yourname/my-cool-tool in package.json
  2. Run the publish command in the terminal
  3. The --access public flag makes a scoped package free + public

Unscoped public packages don't need --access; scoped ones do, otherwise npm assumes private (a paid feature).

4. Bump the version with npm version

Rather than hand-editing the version, let npm do it — it updates package.json and creates a matching git tag in one step, following the semver rules from the versioning chapter:

Increase the version correctly

Terminal
$ npm version patch   # 1.0.0 → 1.0.1  (bug fix)
$ npm version minor   # 1.0.1 → 1.1.0  (new feature)
$ npm version major   # 1.1.0 → 2.0.0  (breaking change)
In VS Code
  1. Run the one that matches your change
  2. It edits package.json and adds a git tag like v1.0.1
  3. Then push with: git push --follow-tags

Choosing patch/minor/major correctly is a promise to your users about whether this update is safe to take.

5. Preview, then publish

Before going live, look at exactly what will be uploaded. Two commands let you check without committing to anything:

Dry-run first, then publish for real

Terminal
$ npm pack --dry-run     # list the files that would be included
$ npm publish --dry-run  # rehearse the publish, upload nothing
$ npm publish            # the real thing
In VS Code
  1. Run the dry-runs and read the file list — make sure no secrets or junk are in it
  2. When it looks right, run npm publish
  3. Your package appears on npmjs.com within moments

A 'prepublishOnly' script in package.json runs automatically before publish — perfect for building or testing first.

Safeguard against accidental publishing: for a project that should never go to npm (like a website — this very repo, for instance), add "private": true to its package.json. npm will then refuse to publish it, full stop.

Made a mistake? You can only fully unpublish a version within 72 hours, and removing popular packages can break other people's projects. The kinder fix is npm deprecate, which leaves the version installable but shows a warning pointing users elsewhere.

Up next: managing several packages in one repository with workspaces.

FAQ

Frequently Asked Questions

How do I publish a package to npm?
Sign in with npm login, make sure package.json has a unique name and a fresh version, then run npm publish. Run npm publish --dry-run first to preview exactly what would be uploaded.
Is publishing to npm free?
Yes. Publishing public packages is free. A scoped package (@you/name) is private by default, so publish it with npm publish --access public to make it free and public.
The name I want is taken — what can I do?
Use a scoped name under your username, like @yourname/the-name. Scopes are always available to you, so you never have to fight over a short global name.
Can I unpublish or fix a published version?
You can fully unpublish only within 72 hours, and removing a popular package can break others. The safer fix is to publish a new version, and use npm deprecate to warn people off the old one.
How do I stop a project being published by accident?
Add "private": true to its package.json. npm will then refuse to publish it — ideal for a website or app that should never go to the registry.