Publishing npm packages under an organization name is how you avoid naming collisions and group related projects.
Let’s see it in action. Imagine you have a common utility function, say fetch-data, and your colleague also creates one. Without scopes, only one of you can publish fetch-data to the public npm registry. If you want to publish it under your company’s name, "my-company," you’d scope it as @my-company/fetch-data. This makes it unique and clearly associated with your organization.
Here’s a typical workflow. First, you need an organization set up on npmjs.com. Once that’s done, you’ll log in to npm from your command line:
npm login
This will prompt you for your username, password, and email. If you have two-factor authentication enabled (which you absolutely should), it will ask for your one-time password.
Now, when you’re in your package’s directory, you’ll modify your package.json file. You need to add the scope to the name field.
{
"name": "@my-company/fetch-data",
"version": "1.0.0",
"description": "A utility to fetch data",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Your Name <your.email@example.com>",
"license": "ISC"
}
Notice the @my-company/ prefix. This tells npm that this package belongs to the "my-company" organization.
After saving package.json, you can publish it just like any other package:
npm publish
If you’re publishing to a private npm registry (like npm Enterprise or a self-hosted Verdaccio instance), you’ll need to configure your .npmrc file to point to that registry. For a public organization, npmjs.com is the default.
The mental model here is that scopes act like namespaces. They provide a hierarchical structure for your packages, preventing conflicts and allowing for better organization, especially in larger teams or companies. When you use @scope/package-name, you’re telling npm to associate this package with a specific entity (your organization or user account). This is crucial for managing multiple related packages, internal tooling, or even just to maintain a distinct brand on the registry.
The npm publish command, when used with a scoped package, automatically targets the registry associated with that scope. For public scopes, this is the npmjs.com registry. For private scopes, it relies on your .npmrc configuration. The scope itself doesn’t inherently change how packages are published, but it dictates where they are published and under whose namespace they reside.
One common point of confusion is with private packages. If you intend to publish a scoped package privately, you’ll need to ensure your npm account has a paid plan that supports private packages, or you’re using a private registry. Simply scoping a package doesn’t automatically make it private; you’d typically use npm publish --access private for public npmjs.com, or configure your private registry accordingly.
The next hurdle you’ll likely encounter is managing versions across multiple scoped packages within your organization, especially if they have interdependencies.