Docs/npm Registry/Scoped Packages

Scoped Packages

Understand how npm scoped packages work with DepAegis, from creating scopes to configuring, publishing, and installing scoped packages in your organization.

What Are Scoped Packages?

A scoped package has a name that starts with an @ symbol followed by the scope name and a slash:

@myorg/ui-components
@myorg/utils
@myorg/design-tokens

Scopes act as namespaces. They solve two key problems:

DepAegis strongly recommends using scoped packages for all private packages. Unscoped packages share a global namespace and have no built-in access control.

Creating a Scope in DepAegis

In DepAegis, a scope is backed by an organization. To create a new scope:

  1. Navigate to Organizations in the DepAegis dashboard.
  2. Click New Organization.
  3. Enter the organization name (e.g. myorg). This becomes the scope: @myorg.
  4. Configure team members and permissions.

Once the organization exists, any package published with the @myorg scope is automatically associated with it.

The organization name must be unique across DepAegis. Choose a name that matches your company or team identity (e.g. acme for @acme/*).

Configuring Scoped Registries in .npmrc

The most common setup is to route a specific scope to DepAegis while keeping the default registry pointing to the public npm registry:

# Default: public npm registry (for packages like react, lodash)
registry=https://registry.npmjs.org/

# Route @myorg packages to DepAegis
@myorg:registry=https://app.depaegis.com/api/v1/npm/

# Authentication for DepAegis
//app.depaegis.com/:_authToken=${DEPAEGIS_TOKEN}

Multiple scopes

If you have multiple organizations on DepAegis, add a registry line for each scope:

@frontend:registry=https://app.depaegis.com/api/v1/npm/
@backend:registry=https://app.depaegis.com/api/v1/npm/
@shared:registry=https://app.depaegis.com/api/v1/npm/
//app.depaegis.com/:_authToken=${DEPAEGIS_TOKEN}

All packages through DepAegis (with upstream proxy)

If DepAegis is configured as an upstream proxy, you can route everything through it:

registry=https://app.depaegis.com/api/v1/npm/
//app.depaegis.com/:_authToken=${DEPAEGIS_TOKEN}
When DepAegis is the default registry, all packages (scoped and unscoped) are fetched from it. DepAegis proxies requests for public packages to the upstream registry if upstream caching is enabled. See Configuring npm for details.

Publishing Scoped Packages

Set the scope in your package.json name field, then publish:

{
  "name": "@myorg/ui-components",
  "version": "1.0.0",
  "description": "Shared UI component library",
  "main": "dist/index.js",
  "types": "dist/index.d.ts"
}
npm publish

npm automatically routes the publish to the registry configured for the @myorg scope in your .npmrc.

Adding publishConfig for safety

To make the target registry explicit (so it works even if someone hasn't configured scoped registries):

{
  "name": "@myorg/ui-components",
  "version": "1.0.0",
  "publishConfig": {
    "registry": "https://app.depaegis.com/api/v1/npm/"
  }
}

First-time publish checklist

  1. Organization @myorg exists in DepAegis.
  2. You have publish permission on the organization.
  3. package.json name starts with @myorg/.
  4. Version is set and hasn't been published before.
  5. .npmrc routes @myorg to DepAegis with a valid token.

Installing Scoped Packages

Once your .npmrc is configured, installing a scoped package is identical to installing any other package:

# Add to dependencies
npm install @myorg/ui-components

# Add to devDependencies
npm install --save-dev @myorg/eslint-config

# Install a specific version
npm install @myorg/ui-components@2.1.0

# Install from a dist-tag
npm install @myorg/ui-components@beta

# Install multiple packages
npm install @myorg/ui-components @myorg/utils @myorg/design-tokens

The entries in your package.json will include the full scoped name:

{
  "dependencies": {
    "@myorg/ui-components": "^2.1.0",
    "@myorg/utils": "~1.0.3"
  }
}

Best Practices for Organization Scopes

Use a consistent naming convention

Keep scope and package names predictable so developers can find and install packages without looking up documentation:

@acme/ui-components
@acme/ui-icons
@acme/api-client
@acme/eslint-config
@acme/tsconfig

One organization per company or business unit

Avoid creating too many organizations. A single organization with well-named packages is easier to manage than many small scopes:

ApproachExampleVerdict
Single org@acme/*Recommended — simple permissions, easy to find
Per-team orgs@acme-fe/*, @acme-be/*OK for large orgs, adds configuration overhead
Per-package orgs@ui-components/*Avoid — too many scopes, hard to manage

Configure at the project level

Use a project-level .npmrc committed to the repo, with the token as an environment variable. This ensures new team members get the correct configuration after cloning:

# .npmrc (committed)
@acme:registry=https://app.depaegis.com/api/v1/npm/
//app.depaegis.com/:_authToken=${DEPAEGIS_TOKEN}

Protect your scope

In DepAegis, configure your organization's permissions so that:

Always use publishConfig

Even if your team's default registry is DepAegis, add publishConfig to every scoped package. This prevents accidental publishes to the wrong registry when someone has a different global .npmrc:

{
  "name": "@acme/my-package",
  "version": "1.0.0",
  "publishConfig": {
    "registry": "https://app.depaegis.com/api/v1/npm/"
  }
}