Part 2 of NPM Package Development
Publishing Your NPM Package: From Code to Registry

Dhruv
Frontend Developer specializing in React
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
- Visit https://www.npmjs.com/signup
- Choose a unique username (this will be part of your package URLs)
- Provide a valid email address
- Create a strong password
- 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.0
→1.0.1
(patch: bug fix)1.0.1
→1.1.0
(minor: new feature)1.1.0
→2.0.0
(major: breaking change)
Publishing Updates
To publish an updated version:
- Update your code
- Update the version in
package.json
- Build the package (
npm run build
) - 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:
- Verify you’re logged in:
npm whoami
- Re-authenticate:
npm login
- 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:
- Ensure
npm run build
completes successfully - Verify
files
field includes build directory - 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.0
→1.0.1
(patch: bug fix)1.0.1
→1.1.0
(minor: new feature)1.1.0
→2.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:
- Check availability first - Visit npmjs.com and search for your desired package name before development
- Use a scoped package - Create a package under your username:
@yourusername/package-name
- Add descriptive suffixes - Use names like
my-package-utils
ormy-package-helpers
- 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:
- Add a new utility function (e.g.,
toCamelCase
) - Update the version using semantic versioning
- Build and test the package
- Publish the updated version
- 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!
Part 2 of NPM Package Development
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.