Publish a Package on the Registry
13 min read·Jan 1, 2025
As an npm user, you can create and publish packages on the npm registry, either to use them in your own projects or to share them with other developers.
In this lesson, we'll create and publish a new package named hello-world.
Set up your npm account
Before being able to publish packages to the npm registry, you will first need to:
-
Create an npm account on the official npm website at npmjs.com/signup.
-
Sign in to your account through the command-line interface interact with the npm registry using the
npm logincommand:$ npm login npm notice Log in on https://registry.npmjs.org/ Login at: https://www.npmjs.com/login?next=/login/cli/a51sf3xf-526a-459a-910b-bcd41436706d Press ENTER to open in the browser... -
Verify which npm account you're currently signed in with using the
npm whoamicommand:$ npm whoami learnbackend
Initialize a new package
Let's create a new directory for the package named hello-world:
~/npm_packages$ mkdir hello-world
~/npm_packages$ cd hello-world
Then, let's create the package.json manifest of the package using the npm init command:
~/npm_packages/hello-world$ npm init
Which should look like this:
{
"name": "hello-world",
"version": "1.0.0",
"description": "A \"Hello, World!\" package in Node.js",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Razvan Ludosanu",
"license": "ISC"
}
Note: Any package published on the npm registry must have a
package.jsonfile that contains at least two mandatory fields:
- A
namefield containing your package's name. It must be one word in lowercase, and may contain hyphens and underscores (e.g.,"name": "hello-world").- A
versionfield containing your package's current version. It must follow the semantic versioning guidelines (e.g.,"version": "1.0.0").
Create an index file
In npm, the index.js file serves as the entry point of the package, and contains the main script that is executed or imported when the package is installed and used.
Let's create a new file named index.js in the top-level directory of the package:
~/npm_packages/hello-world$ touch index.js
And let's write a module that exports a single function named helloWorld() that outputs the string "Hello, World!":
// File: index.js
function helloWorld() {
console.log('Hello, World!');
}
module.exports = helloWorld;
Create a README file
A Readme file is a type of technical software documentation written in plain text.
It usually contains configuration, installation and operating instructions, as well as features, known bugs, licensing and contact information.
Moreover, the npm website and platforms such as Github automatically promote this file as a sort of project homepage, making it the first thing developers and end-users see.
Let's create a new file named README.md (or Readme.md) in the top-level directory of the package:
~/npm_packages/hello-world$ touch README.md
Within this file, let's write the installation and usage instructions of the package in the Markdown format:
# hello-world
Prints "Hello, World!" into the console.
## Getting Started
### Prerequisites
You'll need to install:
- Node.js
- npm
### Installation
Install the package using npm:
`` `shell
$ npm install @username/hello-world
`` `
### Usage
To use the package:
`` `javascript
const helloWorld = require('@username/hello-world');
helloWorld();
`` `
## Authors
- Razvan Ludosanu
## Licence
ISC
Perform pre-publishing verifications
Before publishing a package, there are several verifications you need to perform in order to make sure that it actually works as intended and is safe to use for you, your organization, and any other developers that will potentially download it.
Keep sensitive data out
The first thing to verify is that all sensitive data has been factored out of the code, including private keys, passwords, personally identifiable information, credit card data, and so on.
The .npmignore file
To prevent specific files from being included in your package, and therefore published to the registry, you can create a .npmignore file.
This file follows the same pattern rules as the .gitignore file and lies in the top-level directory of your package.
Notes:
If there's no
.npmignorefile, but there is a.gitignorefile,npmwill ignore the files matched by the.gitignorefile instead.npm automatically ignores everything in the
node_modulesdirectory, except for bundled dependencies.The following files are never ignored, even if added to the
.npmignorefile:
package.jsonREADME(and its variants)CHANGELOG(and its variants)LICENSE/LICENCE
Check the packaged files
Once you've created the .npmignore file, you can verify which files will be included in your package using the npm pack command with the --dry-run flag:
$ npm pack --dry-run
This will simulate the creation of a tarball (i.e. an archive file) and give you details about how the package will be uploaded on the npm registry.
For example:
$ npm pack --dry-run
npm notice
npm notice 📦 hello-world@1.0.0
npm notice === Tarball Contents ===
npm notice 88B index.js
npm notice 260B package.json
npm notice === Tarball Details ===
npm notice name: hello-world
npm notice version: 1.0.0
npm notice filename: hello-world-1.0.0.tgz
npm notice package size: 356 B
npm notice unpacked size: 348 B
npm notice shasum: 6ac8e40c2c9bbce01b985a0044dd23070c0a7cbf
npm notice integrity: sha512-lgrrBTwJy1Jnv[...]9FuALnATS20Yg==
npm notice total files: 2
npm notice
hello-world-1.0.0.tgz
Check the package installation
The last thing to verify is that your package installation actually works.
To test a local package, you can:
-
Create a temporary project.
$ mkdir ~/projects/package-test $ cd ~/projects/package-test -
Install the local package you want to test with
npm installusing its path name:~/projects/package-test$ npm install ~/npm_packages/hello-world -
Create a new test file and import the package into it:
// File: test.js const helloWorld = require('hello-world'); helloWorld(); -
Execute the script:
~/projects/package-test$ node test.js Hello, World!
Publish packages to the npm registry
Scoped and unscoped packages
When signing up for an npm user account or creating an organization, you are granted a scope that matches your user or organization name.
This scope can be used as a namespace, allowing you to create a package with the same name as a package created by another user or organization without conflict.
Unscoped packages
To create an unscoped package, all you have to do is make sure that the name of your package is unique across the npm registry, which can be easily verified using the npm search command.
$ npm search <package>
Scoped packages
To create a scoped package, on the other hand, all you have to do is prefix the name of the package with your username or the name of your organization in the package.json file:
{
"name": "@<username>/<package>",
"version": "<version>"
}
Where:
<username>is the name of your user or organization on npm.<package>is the name of your package.<version>is the version number of your package.
For example:
{
"name": "@learnbackend/hello-world",
"version": "1.0.0"
}
Public and private packages
By default, all packages published on the npm registry are public, which means that they are accessible and downloadable by all users.
Private packages, on the other hand, are packages that are only accessible by you or members of your organization.
Note: While npm provides unlimited hosting for public packages, you can only publish private packages on the npm registry if you signed up for a paid account.
Publish a package
Once the current version of your package is ready to be published, you can use the npm publish command to upload it on the public npm registry.
$ npm publish
It will then be visible and downloadable by everyone.
To publish a private package, on the other hand, you can use the --access flag and set its value to restricted.
$ npm publish --access=restricted
It will then be visible and downloadable by you and chosen collaborators only.
Note: Only scoped packages can be set to restricted.
Summary
Here's a summary of what you've learned in this lesson:
- The
npm logincommand is used to sign in to the npm registry. - The
README.mdfile serves as a package homepage on npmjs and Github. - The
.npmignorefile is used to prevent files and directories from being published. - The
npm pack --dry-runcommand is used to simulate the creation of a tarball of your package. - The
@usernameexpression is used to create scoped packages. - The
npm publishcommand is used to publish a package to the npm registry.
Enjoying the courses?
I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:
Support BackendBrewery