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:

  1. Create an npm account on the official npm website at npmjs.com/signup.

  2. Sign in to your account through the command-line interface interact with the npm registry using the npm login command:

    $ 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...
    
  3. Verify which npm account you're currently signed in with using the npm whoami command:

    $ 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.json file that contains at least two mandatory fields:

  • A name field containing your package's name. It must be one word in lowercase, and may contain hyphens and underscores (e.g., "name": "hello-world").
  • A version field 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 .npmignore file, but there is a .gitignore file, npm will ignore the files matched by the .gitignore file instead.

  • npm automatically ignores everything in the node_modules directory, except for bundled dependencies.

  • The following files are never ignored, even if added to the .npmignore file:

    • package.json
    • README (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:

  1. Create a temporary project.

    $ mkdir ~/projects/package-test
    $ cd ~/projects/package-test
    
  2. Install the local package you want to test with npm install using its path name:

    ~/projects/package-test$ npm install ~/npm_packages/hello-world
    
  3. Create a new test file and import the package into it:

    // File: test.js
    
    const helloWorld = require('hello-world');
    
    helloWorld();
    
  4. 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 login command is used to sign in to the npm registry.
  • The README.md file serves as a package homepage on npmjs and Github.
  • The .npmignore file is used to prevent files and directories from being published.
  • The npm pack --dry-run command is used to simulate the creation of a tarball of your package.
  • The @username expression is used to create scoped packages.
  • The npm publish command 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
Publish a Package on the Registry in npm | Backend Brewery