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.Guide
Turn your own code into a package other people can install. Here's the whole flow, safely.
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.
Create a free account at npmjs.com, then connect your terminal to it:
Log the terminal into npm
$ npm login
$ npm whoami # confirms who you're logged in as npm login — it opens a browser to authenticatenpm whoami should print your usernameEnabling two-factor authentication on your npm account is strongly recommended, especially before 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.
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
$ npm publish --access public @yourname/my-cool-tool in package.jsonUnscoped public packages don't need --access; scoped ones do, otherwise npm assumes private (a paid feature).
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
$ 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) Choosing patch/minor/major correctly is a promise to your users about whether this update is safe to take.
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
$ 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 npm publishA '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
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.@you/name) is private by default, so publish it with npm publish --access public to make it free and public.@yourname/the-name. Scopes are always available to you, so you never have to fight over a short global name.npm deprecate to warn people off the old one."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.