JavaScript NPM Package Development

Publishing Your NPM Package: From Code to Registry

Featured image for Publishing Your NPM Package: From Code to Registry
Dhruv

Dhruv

Frontend Developer specializing in React

12 min read

Introduction: Publishing Your Package to the World

You’ve built your package, configured all the necessary files, and tested your build. Now comes the exciting part: sharing your creation with the world by publishing it to the NPM registry. This chapter will guide you through every step of the publication process, from creating your NPM account to managing your published package.

Publishing to NPM transforms your local project into a globally accessible resource that thousands of developers can install and use in their projects. Let’s make sure you do it right.

Complete Code: The full source code for this tutorial is available on GitHub: how-to-make-npm-package/ex1/strings


Understanding NPM Registry and Publication

The NPM registry serves as a massive database containing millions of JavaScript packages. When you run npm install package-name, you’re downloading from this central repository. Publishing your package makes it part of this ecosystem, accessible to developers worldwide.

Key Concepts

  • Registry - The central database storing all NPM packages
  • Publication - The process of uploading your package to the registry
  • Versions - Each publication creates a new version of your package
  • Access Control - Determines who can install and modify your package

Preparing Your Package for Publication

Before publishing, we need to ensure our package is properly configured and includes only the necessary files.

Configure Publication Files

The files field in package.json controls which files are included in your published package. We already added this in the previous chapter, but let’s verify it’s correct:

{
	"files": ["lib"]
}

This ensures only our built code (in the lib directory) gets published, along with automatically included files like package.json, README.md, and LICENSE.

Verify Publication Contents

Run a dry-run to see exactly what will be published:

npm publish --dry-run

Expected Output:

npm notice
npm notice 📦 [email protected]
npm notice === Tarball Contents ===
npm notice 1.1kB LICENSE
npm notice 891B README.md
npm notice 1.2kB lib/index.cjs
npm notice 956B lib/index.esm.js
npm notice 445B lib/types/index.d.ts
npm notice 1.8kB package.json
npm notice === Tarball Details ===
npm notice name: string-manipulation-examples
npm notice version: 1.0.0
npm notice filename: string-manipulation-examples-1.0.0.tgz
npm notice package size: 2.1 kB
npm notice unpacked size: 6.4 kB
npm notice shasum: [shasum-hash]
npm notice integrity: [integrity-hash]
npm notice total files: 6
npm notice

Perfect! Our package includes only the essential files: our built code, documentation, license, and package configuration.

Quick Tip: Always run --dry-run before publishing to catch any file inclusion issues early.


Creating Your NPM Account

To publish packages, you need an NPM account. The process is straightforward and free for public packages.

Sign Up for NPM

  1. Visit https://www.npmjs.com/signup
  2. Choose a unique username (this will be part of your package URLs)
  3. Provide a valid email address
  4. Create a strong password
  5. Complete email verification

Important: Your username becomes part of your package’s identity, so choose something professional and memorable.

Verify Your Account

After signup, check your email for a verification link. You must verify your email before publishing packages.


NPM Authentication via Terminal

Publishing happens through the command line, so you need to authenticate your terminal session with your NPM account.

Login to NPM

Check if you’re already logged in:

npm whoami

If you see an authentication error, you need to log in:

npm login

This command will:

  • Prompt you with a login URL
  • Open your browser for authentication
  • Request a one-time password (OTP) sent to your email
  • Establish an authenticated session

Example Login Flow:

$ npm login
npm notice Log in on https://registry.npmjs.org/
Login at:
https://www.npmjs.com/login?next=/login/cli/050fdde6-2c8f-4bb5-bb94-a35683c6a12e
Press ENTER to open in the browser...

Logged in on https://registry.npmjs.org/.

Verify Authentication

Confirm you’re logged in with the correct account:

npm whoami

Expected Output:

your-npm-username

Publishing Your Package

With authentication complete, you’re ready to publish your package to the world.

Final Pre-Publication Checklist

Before hitting publish, verify:

  • Package builds successfully (npm run build)
  • All tests pass (if you have tests)
  • README.md contains usage examples
  • Version number is appropriate
  • files field includes only necessary files
  • You’re logged into the correct NPM account

Publish to NPM Registry

Execute the publish command:

npm publish

Successful Publication Output:

npm notice
npm notice 📦 [email protected]
npm notice === Tarball Contents ===
npm notice 1.1kB LICENSE
npm notice 891B README.md
npm notice 1.2kB lib/index.cjs
npm notice 956B lib/index.esm.js
npm notice 445B lib/types/index.d.ts
npm notice 1.8kB package.json
npm notice === Tarball Details ===
npm notice name: string-manipulation-examples
npm notice version: 1.0.0
npm notice filename: string-manipulation-examples-1.0.0.tgz
npm notice package size: 2.1 kB
npm notice unpacked size: 6.4 kB
npm notice shasum: abc123...
npm notice integrity: sha512-...
npm notice total files: 6
npm notice

[email protected]

Congratulations! Your package is now live on the NPM registry.


Verifying Your Published Package

Check on NPM Website

Visit https://www.npmjs.com/package/string-manipulation-exampless to see your package’s NPM page. This page displays:

  • Package information and stats
  • README content
  • Version history
  • Installation instructions
  • Dependencies

Test Installation

Create a test project to verify your package installs and works correctly:

mkdir test-package
cd test-package
npm init -y
npm install your-package-name

Test the Package:

// test.js
const { capitalizeFirstLetter, slugifyText } = require('your-package-name');

console.log(capitalizeFirstLetter('hello world')); // "Hello world"
console.log(slugifyText('Hello World Example')); // "hello-world-example"

Understanding Package Versions and Updates

NPM uses semantic versioning (semver) to manage package versions. Understanding this system is crucial for maintaining your package.

Semantic Versioning Format

Version numbers follow the format: MAJOR.MINOR.PATCH

  • MAJOR - Breaking changes that require user code updates
  • MINOR - New features that maintain backward compatibility
  • PATCH - Bug fixes and small improvements

Examples:

  • 1.0.01.0.1 (patch: bug fix)
  • 1.0.11.1.0 (minor: new feature)
  • 1.1.02.0.0 (major: breaking change)

Publishing Updates

To publish an updated version:

  1. Update your code
  2. Update the version in package.json
  3. Build the package (npm run build)
  4. Publish (npm publish)

Version Update Commands:

npm version patch # 1.0.0 → 1.0.1
npm version minor # 1.0.0 → 1.1.0
npm version major # 1.0.0 → 2.0.0

These commands automatically update package.json and create git tags.


Common Publication Issues and Solutions

Package Name Already Exists

Error: 403 Forbidden - PUT https://registry.npmjs.org/package-name - You do not have permission to publish "package-name"

Solution: Choose a unique package name. Check availability at npmjs.com before development.

Authentication Problems

Error: 401 Unauthorized - PUT https://registry.npmjs.org/package-name

Solution:

  1. Verify you’re logged in: npm whoami
  2. Re-authenticate: npm login
  3. Check your account has email verification

Version Already Published

Error: 403 Forbidden - PUT https://registry.npmjs.org/package-name - You cannot publish over the previously published versions

Solution: Increment your version number in package.json before publishing.

Build Files Missing

Error: Package installs but imports fail

Solution:

  1. Ensure npm run build completes successfully
  2. Verify files field includes build directory
  3. Check entry points in package.json match actual file locations

Post-Publication Best Practices

Update Your README

Add installation and usage instructions to your README:

## Installation

```bash
npm install your-package-name
```

Usage

import { capitalizeFirstLetter, slugifyText } from 'your-package-name';

// Capitalize first letter
const result = capitalizeFirstLetter('hello world');
console.log(result); // "Hello world"

// Create URL-friendly slugs
const slug = slugifyText('My Blog Post Title');
console.log(slug); // "my-blog-post-title"

Monitor Package Usage

Track your package’s adoption through:

  • Download statistics on your NPM package page
  • GitHub stars and issues if you linked your repository
  • User feedback through issues and pull requests

Maintain Your Package

Regular maintenance keeps your package healthy:

  • Respond to issues and questions from users
  • Update dependencies to patch security vulnerabilities
  • Add new features based on user requests
  • Improve documentation as the package evolves

Key Takeaways

  • Preparation is crucial - Always verify your package contents before publishing using --dry-run.
  • Authentication matters - Ensure you’re logged into the correct NPM account before publishing.
  • Semantic versioning - Follow semver principles to help users understand update impact.
  • Testing is essential - Always test your published package in a separate project.
  • Maintenance is ongoing - Publishing is just the beginning; maintaining and improving your package keeps it valuable.

Quick Tips for Success

  • Choose unique names - Check NPM registry before settling on a package name.
  • Write clear documentation - Good README files dramatically increase package adoption.
  • Version thoughtfully - Breaking changes should increment major version numbers.
  • Test thoroughly - Publish to a test account first if you’re unsure about the process.

Quiz: Test Your Understanding

Question 1: Package Publication

What does the files field in package.json control?

Click to reveal answer

The files field specifies which files and directories should be included when your package is published to NPM. It acts as a whitelist, ensuring only the necessary files (like your built lib directory) are published while excluding development files, source code, and other artifacts.

Example:

{
  "files": ["lib", "README.md"]
}

This would only publish the lib directory and README file, excluding everything else.

Question 2: Semantic Versioning

What’s the difference between major, minor, and patch version updates?

Click to reveal answer

Major Version (X.0.0): Breaking changes that require users to update their code. These are incompatible with previous versions.

Minor Version (0.X.0): New features that maintain backward compatibility. Users can upgrade without breaking their existing code.

Patch Version (0.0.X): Bug fixes and small improvements that don’t add new features or break existing functionality.

Example:

  • 1.0.01.0.1 (patch: bug fix)
  • 1.0.11.1.0 (minor: new feature)
  • 1.1.02.0.0 (major: breaking change)

Question 3: Publication Verification

How can you verify which files will be included in your published package?

Click to reveal answer

Use the --dry-run flag with the publish command:

npm publish --dry-run

This command shows exactly what files will be included in your published package without actually publishing it. It displays:

  • Complete list of files to be published
  • Package size and tarball details
  • File sizes and counts
  • Integrity hashes

This is essential for catching file inclusion issues before they reach the registry.

Question 4: Package Name Conflicts

What should you do if you get a “package name already exists” error?

Click to reveal answer

If you get a “package name already exists” error, you need to choose a different package name. Here are your options:

  1. Check availability first - Visit npmjs.com and search for your desired package name before development
  2. Use a scoped package - Create a package under your username: @yourusername/package-name
  3. Add descriptive suffixes - Use names like my-package-utils or my-package-helpers
  4. Use unique prefixes - Add your name or organization: yourname-string-utils

Remember that package names are globally unique across the entire NPM registry.


Practical Assignment: Update and Publish

Assignment: Update Your Package

Add a new utility function to your string manipulation package, increment the version appropriately, and publish the update. Document the changes in your README.

Steps:

  1. Add a new utility function (e.g., toCamelCase)
  2. Update the version using semantic versioning
  3. Build and test the package
  4. Publish the updated version
  5. Verify the update appears on NPM

Implementation Example

Add to src/toCamelCase.ts:

export function toCamelCase(str: string): string {
	return str
		.toLowerCase()
		.replace(/[^a-z0-9]+(.)/g, (_, chr) => chr.toUpperCase());
}

Update src/index.ts:

import { capitalizeFirstLetter } from './capitalizeFirstLetter';
import { slugifyText } from './slugifyText';
import { truncateString } from './truncateString';
import { reverseWords } from './reverseWords';
import { toCamelCase } from './toCamelCase';

export {
	capitalizeFirstLetter,
	slugifyText,
	truncateString,
	reverseWords,
	toCamelCase,
};

Update version and publish:

npm version minor
npm run build
npm publish

Bonus Challenge: Add Tests

Create a simple test file to verify your new function works correctly:

// test.js
import { toCamelCase } from './lib/index.esm.js';

console.log(toCamelCase('hello world')); // "helloWorld"
console.log(toCamelCase('my-variable-name')); // "myVariableName"

Next Steps

Congratulations! You’ve successfully published your first NPM package and learned how to manage updates. In future chapters, we’ll explore advanced topics like:

  • Automated releases with GitHub Actions
  • Comprehensive testing strategies
  • Package optimization techniques
  • Documentation generation
  • Performance monitoring
  • Security best practices

Your package is now part of the global JavaScript ecosystem, ready to help developers around the world.


Chapter Summary

In this chapter, we’ve covered:

NPM Registry Understanding - How the registry works and what publication means
Account Setup - Creating and verifying your NPM account
Authentication - Logging in and managing your credentials
Publication Process - Step-by-step guide to publishing your package
Version Management - Understanding semantic versioning and updates
Post-Publication - Best practices for maintaining your published package

What’s Next? Your package is live! In the next chapter, we’ll explore advanced topics like automated testing, continuous integration, and package optimization techniques.

Found this helpful? Share this post!

Dhruv

Dhruv

Dynamic Frontend Developer specializing in React.js and Next.js. Creating engaging web experiences with modern technologies and beautiful animations. Always up for learning.