Publishing npm Packages
Publishing to npm means packaging your code with a correct package.json, versioning it with semver, and running npm publish so anyone can install it with npm install — turning your project into a reusable, shareable package.
Learn Publishing npm Packages in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll learn the package.json fields that matter (name, version, main, exports, files), how semver decides each version bump, how to log in and publish, what scoped packages and .npmignore do, and why you often publish a built dist folder.
What You'll Learn in This Lesson
1️⃣ The package.json Fields That Matter
Your package.json is the manifest npm reads. The critical fields: name (unique on npm), version (semver), main (the entry file loaded when someone imports you), exports (a modern, more precise entry map), and files (an allowlist of what to publish). The runnable example assembles one.
2️⃣ Names & semver Validation
npm is strict about two fields. The name must be lowercase and URL-safe, and the version must follow semver : MAJOR.MINOR.PATCH . Bump patch for fixes, minor for new compatible features, major for breaking changes. The validator below flags a bad name and a malformed version.
3️⃣ Logging In & Publishing
With a valid manifest, publishing is a few commands. npm login authenticates you, npm version patch|minor|major bumps the version (and tags git), npm publish --dry-run shows exactly what will ship, and npm publish sends it. Scoped packages are private by default, so add --access public .
Your turn. The version bumper below works once you fill in the single blank marked ___ . Follow the 👉 hint, then run it.
No blanks — just a brief and an outline. Build a scoped package manifest that ships only the build folder and is published publicly. Build it, run it, and compare with the example output.
📋 Quick Reference — Publishing
Practice quiz
Which command logs you in to npm before publishing?
- npm login
- npm auth
- npm signin
- npm connect
Answer: npm login. npm login creates an auth token in ~/.npmrc.
What does npm version patch do to 1.0.0?
- Makes it 2.0.0
- Makes it 1.0.1
- Makes it 1.1.0
- Leaves it unchanged
Answer: Makes it 1.0.1. A patch bump increments the last number: 1.0.0 to 1.0.1.
Which version bump is correct for a BREAKING change?
- npm version patch
- npm version minor
- npm version major
- npm version build
Answer: npm version major. Breaking changes increment the MAJOR number (e.g. 1.0.0 to 2.0.0).
How can you preview EXACTLY what will be published without shipping?
- npm publish --preview
- npm test
- npm pack --list
- npm publish --dry-run
Answer: npm publish --dry-run. npm publish --dry-run shows the file list without actually publishing.
Why do scoped packages need --access public to publish?
- They are private by default
- They are deprecated
- They cost money otherwise
- They require two-factor auth
Answer: They are private by default. Scoped (@you/name) packages default to private; --access public makes them public.
What does the "files" field in package.json control?
- Which tests run
- Which files actually get published
- The author list
- The license
Answer: Which files actually get published. The files allowlist limits what is included in the published tarball.
Which file keeps junk (like tests or .env) out of the published package?
- package-lock.json
- tsconfig.json
- .npmignore
- README.md
Answer: .npmignore. .npmignore (or the files allowlist) excludes files from publishing.
Which name is valid for an npm package?
- My Package
- GREET CLI
- Greet_CLI Pro
- greet-cli
Answer: greet-cli. npm names must be lowercase and URL-safe, like greet-cli.
What format must a package version follow?
- MAJOR.MINOR.PATCH (e.g. 1.0.0)
- A single number
- A date
- A word like stable
Answer: MAJOR.MINOR.PATCH (e.g. 1.0.0). Versions must be semver: three dot-separated numbers.
What does the "main" field in package.json specify?
- The author
- The entry file loaded when someone requires the package
- The test command
- The license URL
Answer: The entry file loaded when someone requires the package. main points to the file returned when someone imports/requires your package.