Internal Packages
nproxy Enterprise lets you host internal (private) packages alongside the public npm registry. Your developers use a single registry URL for both public and private packages -- no separate registry, no extra configuration.
Requires the Enterprise plan.
How it works
Internal packages are identified by npm scope. You configure which scopes are internal (e.g. @acme), and any package under those scopes is served from nproxy's storage instead of the upstream npm registry.
When a developer runs npm install:
- The proxy extracts the package name from the request
- If the package scope matches one of your configured internal scopes, it is served from nproxy's internal storage
- If not, the request is proxied to the upstream npm registry with security rules applied
Internal packages bypass security rules because your organization controls the code. Each organization's packages are isolated — you cannot access another organization's internal packages.
Configuring internal scopes
In the dashboard, go to Settings and add your internal scopes to the Internal Scopes list. Scopes must start with @:
["@acme", "@acme-internal"]
Or via the API:
curl -X PUT https://nproxy.app/api/v1/orgs/{orgId}/settings \
-H "Authorization: Bearer <session>" \
-H "Content-Type: application/json" \
-d '{"internalScopes": ["@acme"]}'
Publishing packages
Publishing requires an API token with the publish scope. Create one in the dashboard under API Tokens.
Publish a package
npm publish --registry https://acme.nproxy.app/
Or set the registry in your package's package.json:
{
"name": "@acme/utils",
"version": "1.0.0",
"publishConfig": {
"registry": "https://acme.nproxy.app/"
}
}
Then run:
npm publish
The proxy accepts the standard npm publish payload. The tarball is stored and the packument is updated atomically.
Publish payload limits
- Maximum payload size: 50 MB
- Duplicate version detection: publishing an already-existing version returns 409 Conflict
- Concurrent publish protection: automatic retry on conflict (up to 3 attempts)
Unpublishing packages
npm unpublish @acme/utils --registry https://acme.nproxy.app/ --force
Unpublishing requires a token with the publish scope. It deletes all tarballs and metadata for the package.
Installing internal packages
No special configuration needed. If your .npmrc points to nproxy, internal packages install just like public ones:
npm install @acme/utils
Tarball URLs point through the proxy (e.g. https://acme.nproxy.app/@acme/utils/-/utils-1.0.0.tgz).
Authentication
All internal package operations require authentication. Even if your organization allows public reads for upstream packages, internal packages always require a valid API token.
| Operation | Required scope |
|---|---|
| Install (read) | proxy |
| Publish | publish |
| Unpublish | publish |
Scoped package support
Internal packages must be scoped (e.g. @acme/utils). Unscoped packages cannot be internal because they would conflict with public npm packages of the same name.
The scope matching is exact: if your internal scopes include @acme, then @acme/utils and @acme/lib are internal, but @acme-corp/utils is not.
Audit events
Internal package operations are logged to the audit trail:
| Event | Description |
|---|---|
package.published | A new version was published. Includes package name, version, and token hash. |
package.signed | A new version was signed with the org's Ed25519 key. Includes keyId. |
package.unpublished | A package was unpublished. Includes package name and token hash. |
Public npm publish
For non-internal packages, npm publish is forwarded to the upstream npm registry. This means you can publish to public npm through the proxy -- you just need a valid npm token (obtained via npm login). The proxy strips nproxy_ tokens before forwarding since npm would not accept them.
Limitations
- Internal packages are scoped only -- unscoped internal packages are not supported
- There is no version-level unpublish;
npm unpublishremoves the entire package - Internal packages do not have security rules applied (they are your own code)
- There is no package search or listing API for internal packages