Shipping a library or internal package requires a clean, intentional tarball.
Before publishing, decide what goes in the tarball. Use the files allow-list in package.json (e.g. ["dist"]) rather than relying on .npmignore; package.json, README and LICENSE are always included. Preview with npm pack --dry-run, which lists every file and the size. Leaked .env files and test fixtures are common mistakes.
Required metadata: a unique name (scoped names like @you/pkg avoid collisions), version, and ideally description, license, repository, engines, plus entry points (exports, covered later).
Versioning: npm version patch|minor|major bumps version, commits and tags in Git (v1.2.4), running preversion/version/postversion scripts. Use npm version prerelease --preid=beta for betas.
Publishing:
npm publishuploads to the registry and moves thelatestdist-tag. Scoped packages default to restricted (private) access; pass--access publicthe first time you publish an open-source one.- Publish prereleases with
--tag nextso they do not becomelatest. prepublishOnlyis the place to run build and tests.- Accounts need 2FA; automation should use trusted publishing from CI rather than long-lived tokens (later lesson).
Mistakes: npm deprecate pkg@1.2.3 "reason" warns users; npm unpublish is only freely allowed within 72 hours (and when nothing depends on the version) and is discouraged, and a version number can never be reused.
Example
# package.json (excerpt):
# "name": "@ann/slugify", "version": "1.0.0",
# "files": ["dist"], "license": "MIT",
# "scripts": { "build": "tsc", "prepublishOnly": "npm run build && npm test" }
npm pack --dry-run
# npm notice package: @ann/slugify@1.0.0
# npm notice 1.1kB LICENSE
# npm notice 642B README.md
# npm notice 2.3kB dist/index.js
# npm notice 812B package.json
# npm notice total files: 4
npm version minor # 1.0.0 -> 1.1.0, git commit + tag v1.1.0
npm publish --access public # first publish of a public scoped package
git push --follow-tags
npm version prerelease --preid=beta # 1.1.1-beta.0
npm publish --tag next # latest stays at 1.1.0Remember
- Use
filesand checknpm pack --dry-runbefore publishing npm versionbumps, commits and tags- Publish prereleases under a non-latest dist-tag
- Versions can never be reused; deprecate instead of unpublishing
Watch out for
- Publishing a beta without
--tag, making it the version everyone installs.