Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to consume private npm packages in React

Managing dependencies in a professional React environment often requires access to proprietary code stored in private registries.
With over 25 years of experience in software development and as the creator of CoreUI, I have architected numerous internal design systems that rely on private npm packages for secure distribution.
The most efficient and modern solution for consuming these packages is to configure a project-level .npmrc file that utilizes environment variables for authentication tokens.
This approach ensures that your credentials remain secure while allowing your React application to build seamlessly across local environments and CI/CD pipelines.

Use a project-level .npmrc file to define your registry and map an environment variable to your authentication token.

# .npmrc
@my-org:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

The configuration above tells npm that any package starting with the @my-org scope should be fetched from the official registry (or a private one like GitHub Packages or Verdaccio) using the token provided in the NPM_TOKEN environment variable. This prevents you from hardcoding sensitive keys into your source control, which is a critical security requirement in enterprise React projects.

Best Practice Note:

Always add .npmrc to your repository but ensure the actual token is never committed; instead, inject it during the build process. At CoreUI, we use this pattern for our PRO versions to maintain a balance between ease of installation and strict access control.

1. Setting up the Project-Level .npmrc

The first step in consuming private packages is creating a configuration file at the root of your React project. Unlike the global configuration located in your home directory, a project-specific .npmrc ensures that every developer on your team uses the same settings.

# .npmrc configuration for scoped private packages
# This file should be committed to your version control system

# Define the registry for your specific scope
@coreui-pro:registry=https://registry.npmjs.org/

# Set up the authentication mapping
# We use a variable placeholder to keep the secret safe
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

# Optional: Always auth ensures npm sends the token for every request to this registry
always-auth=true

By defining the scope (e.g., @coreui-pro), you tell the package manager exactly which packages require special permissions. This prevents unnecessary overhead when installing public packages like react or react-dom.

2. Managing the Authentication Token Securely

Security is paramount when dealing with private codebases. You should never paste your plain-text npm token directly into the .npmrc file. Instead, use a local .env file for development and environment secrets for production.

# .env (DO NOT COMMIT THIS FILE)
# Generate this token from your npm profile settings
NPM_TOKEN=npm_000000000000000000000000000000

To make the environment variable available to npm during installation, you might need to export it in your terminal session. If you are using a tool like dotenv in your build script, ensure it is loaded before the package manager runs. Most modern shells and CI environments handle the ${NPM_TOKEN} syntax in .npmrc natively.

3. Configuring Scoped Packages in package.json

Once your authentication is configured, you can add the private package to your package.json. Scoped packages are the standard way to organize private modules in the npm ecosystem.

{
  "name": "my-secure-react-app",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "@coreui/react": "^5.0.0",
    "@my-org/private-utils": "^1.2.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build"
  }
}

After adding the dependency, run npm install. The package manager will look at your .npmrc, find the @my-org scope, use the NPM_TOKEN from your environment, and download the package into node_modules.

4. Consuming the Private Package in React Components

Using a private package in your React code is identical to using a public one. The benefit is that you can now share proprietary logic or UI components across multiple internal projects.

import React from 'react'
import { CAlert } from '@coreui/react'
// Importing from our private package
import { formatSecureDate } from '@my-org/private-utils'

const DashboardNotice = () => {
  // Example of using a utility from a private package
  // Similar to: /answers/how-to-format-date-as-yyyy-mm-dd-in-javascript/
  const today = formatSecureDate(new Date())

  return (
    <div className='p-4'>
      <CAlert color='info'>
        Welcome back! Today is {today}.
        Your private session is active.
      </CAlert>
    </div>
  )
}

export default DashboardNotice

In this example, we utilize a standard CoreUI Alert component alongside a custom formatting utility from our private repository. This maintains consistency while keeping business logic encapsulated.

5. Integrating with CI/CD Pipelines

To build your React application in a CI/CD environment (like GitHub Actions, GitLab CI, or Jenkins), you must provide the NPM_TOKEN to the runner. Here is how you would configure a GitHub Actions workflow.

# .github/workflows/build.yml
name: React Build
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          # This automatically creates a .npmrc file
          registry-url: 'https://registry.npmjs.org'
          scope: '@my-org'

      - name: Install Dependencies
        run: npm install
        env:
          # Inject the secret from GitHub Action Secrets
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Build Project
        run: npm run build

The secrets.NPM_TOKEN should be added to your GitHub repository settings under Secrets and Variables. This ensures that even the build logs do not expose your private credentials.

6. Troubleshooting Common Issues

When consuming private packages, you might encounter a “404 Not Found” or “401 Unauthorized” error. This usually indicates a configuration mismatch in the .npmrc or a missing environment variable.

  • 404 Error: Often means the scope isn’t correctly mapped to the registry. Double-check that @your-scope:registry is defined.
  • 401 Error: This usually means the token is invalid, expired, or the environment variable isn’t being read. Run echo $NPM_TOKEN (or dir env:NPM_TOKEN on Windows) to verify the variable is set in your current shell.
  • Check if your string contains a substring: If you are dynamically building registry URLs, ensure you are correctly validating them. You can learn how to check if a string contains a substring in JavaScript to verify your environment configurations.

7. Using Private CoreUI PRO Packages

If you are using CoreUI PRO, the process is very similar. Our private packages are hosted on our secure registry to provide you with advanced components and templates.

# Example for CoreUI PRO
@coreui-pro:registry=https://registry.coreui.io/
//registry.coreui.io/:_authToken=${COREUI_PRO_TOKEN}

This setup allows you to keep your Admin Dashboard Template updated with the latest security patches and features without manual downloads. By integrating private npm packages correctly, you transform your React development workflow into a scalable, enterprise-grade architecture.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author