> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superblocks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Private registries

> Keep app dependencies secure and compliant by routing package installs through your own trusted npm registries

export const Alert = ({type, title, children}) => {
  const getIcon = () => {
    switch (type) {
      case 'info':
        return "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10 0C4.477 0 0 4.477 0 10s4.477 10 10 10 10-4.477 10-10S15.523 0 10 0zm0 15c-.552 0-1-.448-1-1s.448-1 1-1 1 .448 1 1-.448 1-1 1zm1-3H9V6h2v6z' fill='%230099FF'/%3E%3C/svg%3E";
      case 'success':
        return "data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10 0C4.477 0 0 4.477 0 10s4.477 10 10 10 10-4.477 10-10S15.523 0 10 0zm4.293 6.293L9 11.586 5.707 8.293c-.391-.391-1.024-.391-1.414 0s-.391 1.024 0 1.414l4 4c.391.391 1.024.391 1.414 0l6-6c.391-.391.391-1.024 0-1.414s-1.024-.391-1.414 0z' fill='%230CC26D'/%3E%3C/svg%3E";
      case 'warning':
        return "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHhtbDpzcGFjZT0ncHJlc2VydmUnIHdpZHRoPScxMDgwJyBoZWlnaHQ9JzEwODAnPjxyZWN0IHdpZHRoPScxMDAlJyBoZWlnaHQ9JzEwMCUnIGZpbGw9J3RyYW5zcGFyZW50Jy8+PHBhdGggZD0nTTEzLjc5NCAxMC43NSA4LjMgMS4yNWExLjUgMS41IDAgMCAwLTIuNiAwbC01LjQ5NCA5LjVBMS40OTQgMS40OTQgMCAwIDAgMS41IDEzaDExYTEuNDkzIDEuNDkzIDAgMCAwIDEuMjk0LTIuMjVNNi41IDUuNWEuNS41IDAgMCAxIDEgMFY4YS41LjUgMCAwIDEtMSAwek03IDExYS43NS43NSAwIDEgMSAwLTEuNS43NS43NSAwIDAgMSAwIDEuNScgc3R5bGU9J3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxO3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1kYXNob2Zmc2V0OjA7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7ZmlsbDojZmY5ZjM1O2ZpbGwtcnVsZTpub256ZXJvO29wYWNpdHk6MScgdHJhbnNmb3JtPSd0cmFuc2xhdGUoLjAyIDE5LjMwNSlzY2FsZSg3Ny4xNCknLz48L3N2Zz4=";
      case 'danger':
        return "data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 0C4.477 0 0 4.477 0 10s4.477 10 10 10 10-4.477 10-10S15.523 0 10 0zm5.707 4.293L10 9.586 4.293 4.293c-.391-.391-1.024-.391-1.414 0s-.391 1.024 0 1.414L8.586 11l-5.707 5.293c-.391.391-.391 1.024 0 1.414s1.024.391 1.414 0L10 12.414l5.707 5.293c.391.391 1.024.391 1.414 0s.391-1.024 0-1.414L11.414 11l5.707-5.293c.391-.391.391-1.024 0-1.414s-1.024-.391-1.414 0z' fill='%23F45252'/%3E%3C/svg%3E";
      case 'note':
        return "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10 0C4.477 0 0 4.477 0 10s4.477 10 10 10 10-4.477 10-10S15.523 0 10 0zm0 15c-.552 0-1-.448-1-1s.448-1 1-1 1 .448 1 1-.448 1-1 1zm1-3H9V6h2v6z' fill='%230099FF'/%3E%3C/svg%3E";
      default:
        return "";
    }
  };
  return <div className={`alert alert--${type}`}>
      <div className="alert-icon" style={{
    backgroundImage: `url("${getIcon()}")`,
    backgroundRepeat: 'no-repeat',
    backgroundPosition: 'center center',
    backgroundSize: '20px',
    width: '24px',
    height: '24px',
    position: 'absolute',
    left: '16px',
    top: '16px'
  }} />
      <div className="alert-content">
        {title && <div className="alert-title">{title}</div>}
        <div className="alert-body">{children}</div>
      </div>
    </div>;
};

<Alert type="note">
  <p>
    <strong>Who can use this feature?</strong><br />
    Organization admins with the appropriate permissions can configure package registry settings.
  </p>
</Alert>

Private package registries put your organization in control of every npm dependency that ships in a Superblocks app. Instead of pulling from the public npm registry, you point Superblocks at the registries your security and platform teams already trust, so the packages your builders and [Clark AI](/building-with-clark/index) install are the ones you've vetted, governed, and approved.

With custom registries you can:

* **Meet security and compliance requirements** by keeping package installs inside your own supply chain, with no unreviewed code from the public internet and a clear approval path for what's allowed
* **Reduce supply-chain risk** by resolving dependencies from an allowlist-gated or scanned registry (e.g. Artifactory, Nexus, Verdaccio) rather than an open ecosystem
* **Reuse what you've already built** by letting builders install your organization's private packages, such as a shared design system, component library, or internal utilities published under your own npm scope (e.g. `@mycompany`)
* **Fit your network model** in egress-restricted environments where all traffic must flow through an internal registry

Once configured, every `npm install` (in both Edit mode and production builds) flows through your registries. Clark checks package availability against them before attempting an install and gives builders clear, actionable feedback when a package isn't available, so problems surface early instead of at deploy time.

## How registries are matched

Superblocks lets you configure two kinds of registry, mirroring how npm resolves packages through an `.npmrc` file:

* A **default registry** (unscoped): the fallback for every package that isn't matched by a scoped registry.
* Any number of **scoped registries**, each pinned to a single npm [scope](https://docs.npmjs.com/cli/using-npm/scope) (e.g. `@mycompany`). Packages under that scope resolve from the scoped registry; everything else falls through to the default.

For example, if a default registry is configured, plus a `@mycompany` scoped registry, `@mycompany/design-system` will resolve from `https://npm.internal.mycompany.com/`, while an unscoped package like `lodash` (or a public-scope package) resolves from the default registry. If no default registry is configured, packages with no matching scoped registry resolve from the public npm registry (registry.npmjs.org).

<Info>
  Scoped registries are optional. If you only need a single registry for all packages, configure the default registry and skip the scoped rows.
</Info>

## Configure the default registry

1. Navigate to **Organization Settings > Package Registry**
2. In the **Default** row under **Package Registries**, enter your **Registry URL**, the full URL of your npm-compatible registry (e.g. `https://artifactory.example.com/api/npm/npm-virtual/`)
3. Optionally enter an **Auth token**, a token with read access to your registry. The token is encrypted at rest and never exposed in the UI after saving
4. Click **Test connection** to verify Superblocks can reach the registry before saving (see [Verify a registry](#verify-a-registry))
5. Click **Save**

| Field            | Description                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------ |
| **Registry URL** | The full URL of your npm-compatible registry. Must use HTTPS                               |
| **Auth token**   | An optional authentication token for the registry. Stored encrypted; redacted after saving |

<Warning>
  The registry URL must use `https://` and must not embed credentials (e.g. `https://user:pass@host/`); use the **Auth token** field instead. HTTP URLs and inline credentials are rejected to prevent secrets from being sent in cleartext.
</Warning>

<Warning>
  Before creating your first app, ensure your registry (or registries) serve the [core required packages](#core-required-packages) and their transitive dependencies. The editor will not start if any are missing.
</Warning>

## Add a scoped registry

Scoped registries route packages under a specific npm scope to a dedicated registry, while all other packages continue to use the [default registry](#configure-the-default-registry).

1. On the **Package Registry** page, click **Add scoped registry**
2. Enter the **Scope** the registry serves, e.g. `@mycompany` (see [Scope format](#scope-format))
3. Enter the **Registry URL** and, optionally, an **Auth token**, using the same rules as the default registry
4. Click **Test connection** to verify the registry
5. Click **Save**

Saved scoped registries appear as collapsible rows under the default registry, each showing its scope, URL, and connection status. Click a row to expand and edit it.

### Scope format

A scope must:

* Start with `@`
* Use only lowercase letters, digits, `.`, `_`, and `-`, beginning with a letter or digit after the `@` (e.g. `@my-company`, `@team.internal`)
* Be unique within your organization; you can configure at most one registry per scope

Scopes are normalized to lowercase, matching how npm itself treats them. Uppercase input (e.g. `@MyCompany`) is lowercased automatically.

<Warning>
  A scope is **fixed once the scoped registry is saved**. To reassign a registry to a different scope, delete the row and add a new one.
</Warning>

## Verify a registry

Click **Test connection** next to any Registry URL to probe the registry before (or after) saving. Superblocks resolves the host, opens a connection, and reports a status badge on the row:

| Badge                                 | Meaning                                                                                                                                                                             |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Reachable**                         | The registry responded and, if a token was supplied, accepted it                                                                                                                    |
| **Reachable, token not verified**     | The registry responded but doesn't expose `/-/whoami`, so the token couldn't be validated. Install problems will only surface when Clark or a build job actually installs a package |
| **Unreachable** (or a specific error) | The probe failed. See the reason below the field                                                                                                                                    |

Common failure reasons:

| Reason                                                                   | Meaning                                          |
| ------------------------------------------------------------------------ | ------------------------------------------------ |
| Couldn't reach the registry                                              | The host could not be resolved or connected to   |
| The registry returned an invalid TLS certificate                         | TLS/certificate validation failed                |
| The registry rejected your auth token                                    | Authentication failed. Check the token           |
| This registry requires authentication (supply an auth token and re-test) | The registry needs a token but none was provided |
| This URL doesn't look like an npm registry                               | The endpoint didn't respond like an npm registry |
| The registry took too long to respond                                    | The probe timed out                              |
| A network proxy blocked the request                                      | An outbound proxy blocked the connection         |

<Note>
  When you edit a saved registry's URL, the stored auth token is **not** reused against the new URL. For security, a stored token is only ever sent to its original host. Enter a new token (or **Clear token**) before saving a URL change.
</Note>

## Manage auth tokens

Auth tokens are optional and are sent to the registry as the npm `_authToken`. Leave the field blank for registries that don't require authentication.

* Tokens are **stored encrypted at rest** and are **never retrievable** from the dashboard after saving; the field shows only a redacted preview.
* To **rotate** a token, enter a new value and save.
* To **remove** a stored token, click **Clear token** and save.

## Network requirements

For Superblocks Cloud (SaaS) organizations, your registry must be reachable from Superblocks' infrastructure. The **Network requirements** section on the Package Registry page lists the source **egress IPs** Superblocks connects from; your registry must accept **TCP/443** from these addresses. Use **Copy** or **Copy all** to add them to your registry's or firewall's allowlist.

<Note>
  The Network requirements section only appears for SaaS deployments where egress IPs are published. [Cloud-prem](/enterprise/cloud-prem/aws) and self-hosted deployments own their own network path to the registry, so no allowlist is shown.
</Note>

## Allow install scripts

Separately from registry configuration, admins can control whether npm packages are allowed to run post-install scripts. This is an organization-wide setting that applies to all package installs regardless of which registry is configured.

Some npm packages run post-install scripts during installation. For example, `sharp` and `better-sqlite3` compile native binaries. Disabling install scripts reduces your supply-chain attack surface by preventing arbitrary code execution at install time, but packages that rely on lifecycle scripts may fail to build.

Toggle **Allow packages to run post-install scripts** on the Package Registry page based on your organization's security posture:

| Setting               | Behavior                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------ |
| **Enabled** (default) | Packages can run post-install scripts normally                                             |
| **Disabled**          | All `npm install` commands include `--ignore-scripts`, blocking lifecycle script execution |

## How Clark interacts with your registry

When a builder asks Clark to install a package, Clark checks your configured registry before attempting the install:

1. Clark queries your registry to confirm the package is available
2. If the package is found, Clark proceeds with the install
3. If the package is **not found** in your registry, Clark explains the situation and suggests the builder contact their admin to add the package to the registry's approved list

This ensures Clark is aware of your registry configuration and can give builders clear feedback when a package install fails.

### Error messages

When a package install fails, Clark provides a structured explanation based on the failure type:

| Error                              | Meaning                                                                                                                       |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Package not in registry**        | The requested package is not available in your organization's registry. Ask your admin to add it to the approved package list |
| **Registry authentication failed** | The configured auth token is invalid or expired. An admin needs to update the token in Package Registry settings              |
| **Registry unreachable**           | The registry could not be reached. Check network connectivity and registry availability                                       |

## Enforcement model

Superblocks synthesizes an `.npmrc` from your configuration (a top-level `registry=` line for the default registry plus one `@scope:registry=` line per scoped registry) and uses it for all Clark-triggered installs across Clark, the dev server, and the build pod. A package under a configured scope always resolves from that scope's registry; everything else resolves from the default. Clark also checks package availability against the matching registry before attempting installs.

For [cloud-prem](/enterprise/cloud-prem/aws) customers who own their network infrastructure, you can combine the Package Registry configuration with network-level controls (e.g. VPC egress rules, NetworkPolicy) that block traffic to `registry.npmjs.org` for full enforcement in egress-restricted environments.

## Core required packages

Every Superblocks application ships with a fixed set of npm dependencies. All of these must be resolvable from your registry, or the editor will not start.

There are two tiers:

* **Platform-critical**: the editor, dev server, and build pipeline require these to function. Clark will never suggest removing them; the only fix for a missing one is for an admin to mirror it into the registry.
* **Template defaults**: included in new apps (e.g. Radix UI, Lucide, Recharts). Clark can refactor these away if a builder asks, but they must be available when an app is first created.

### Platform-critical packages

These packages cannot be removed or replaced. If any are missing from your registry, the editor will fail to start and Clark cannot work around it.

#### `@superblocksteam/*` scoped packages

All packages under the `@superblocksteam` scope are platform-owned and protected. These are published to the public npm registry (`registry.npmjs.org`). They resolve through your **default** registry unless you add a scoped registry for `@superblocksteam`. If you do, that registry must serve every package below, or the editor will not start.

| Package                            | Role                                                     |
| ---------------------------------- | -------------------------------------------------------- |
| `@superblocksteam/library`         | Core runtime library (component model, state, evaluator) |
| `@superblocksteam/sdk-api`         | SDK API type definitions                                 |
| `@superblocksteam/library-shared`  | Shared types consumed by the library and platform        |
| `@superblocksteam/shared`          | Platform-wide shared types and protobuf definitions      |
| `@superblocksteam/types`           | Generated protobuf type bindings                         |
| `@superblocksteam/sabs-types`      | Build service type definitions                           |
| `@superblocksteam/fast-deep-equal` | Deep-equality utility                                    |
| `@superblocksteam/cli`             | Official Superblocks CLI (local dev, resource sync)      |
| `@superblocksteam/iso-currency`    | Currency formatting and data                             |

#### Unscoped platform packages

| Package             | Role                                 |
| ------------------- | ------------------------------------ |
| `react`             | React runtime                        |
| `react-dom`         | React DOM renderer                   |
| `react-router`      | App page routing                     |
| `vite`              | Dev server and production build tool |
| `typescript`        | Type checking in the build pipeline  |
| `@tailwindcss/vite` | Tailwind CSS Vite plugin             |
| `tailwindcss`       | Tailwind CSS framework               |

### Full dependency closure

A newly created app installs approximately 780 npm packages (direct + transitive). The exact set depends on your Superblocks version.

<Tabs>
  <Tab title="Pull-through cache (Artifactory, Nexus, Verdaccio proxy)">
    If your registry is configured as a remote proxy, it will automatically fetch transitive dependencies on cache miss. Ensure the platform-critical packages listed above are reachable through your proxy, and the rest will resolve automatically.

    The first app creation may be slower than usual while the cache warms.
  </Tab>

  <Tab title="Curated allowlist">
    If your registry requires explicit approval for every package, you need the full dependency closure. Download the complete package list and feed it to your approval pipeline:

    <a href="/admin/assets/superblocks-core-packages.json" download>Download superblocks-core-packages.json</a>

    This JSON file lists all \~780 packages with their versions. Use it to verify your registry covers every required dependency.

    <Note>
      Approximately 52 of these packages are **platform-specific optional binaries** (`@esbuild/linux-x64`, `@rollup/rollup-darwin-arm64`, etc.). npm only installs the ones matching the target platform, but your registry must serve the binaries for every platform where Superblocks runs.
    </Note>
  </Tab>
</Tabs>

<Info>
  Package versions and transitive dependencies may change between Superblocks releases. Use the [Superblocks MCP server](/admin/mcp-server) to query packages currently in use across your organization for the latest inventory.
</Info>

## Package inventory

Admins can view the distinct set of npm packages in use across all applications in the organization using the [Superblocks MCP server](/admin/mcp-server). Compare the output against the [core required packages](#core-required-packages) to verify your registry covers the baseline. This is useful for:

* **Registry reconciliation**: compare installed packages against what your private registry serves to find gaps before they cause install failures
* **Audit and compliance**: maintain visibility into your organization's npm dependency footprint
* **Migration planning**: identify which apps need attention when tightening registry policies

Ask your AI coding agent:

```text theme={null}
What npm packages are in use across my Superblocks organization?
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Installs fail with 'package not in registry'">
    The requested package exists on public npm but has not been added to your private registry. If your registry is a **pull-through cache** (e.g. Artifactory configured as a remote proxy), the package should appear automatically on first request. If your registry uses a **curated allowlist**, your security team needs to approve and mirror the package before it can be installed.
  </Accordion>

  <Accordion title="Installs fail with 'registry authentication failed'">
    The auth token saved in Package Registry settings is invalid or expired. Navigate to **Organization Settings > Package Registry**, enter a fresh token, and save. Tokens from registries like Artifactory and Nexus may have expiration policies. Coordinate with your registry administrator on rotation schedules.
  </Accordion>

  <Accordion title="Installs fail with 'registry unreachable'">
    Superblocks could not reach your registry. Common causes:

    * The registry URL is incorrect or has a typo
    * The registry is behind a firewall that does not allow traffic from Superblocks infrastructure
    * The registry service is temporarily down

    Verify the URL is correct and that your registry is accessible from the network where Superblocks runs. For [cloud-prem](/enterprise/cloud-prem/aws) deployments, ensure the Superblocks data plane has network connectivity to your registry.
  </Accordion>

  <Accordion title="Editor fails to start after configuring a private registry">
    The editor requires approximately 780 npm packages (direct + transitive) to boot a new 3.0 app. If any are missing from your registry, the dev server will fail to start. Check the [core required packages](#core-required-packages) section and ensure all platform-critical packages and their transitive dependencies are available. For pull-through caches, the first app creation may be slower than usual while packages are fetched on cache miss.
  </Accordion>

  <Accordion title="Scoped packages resolve from the wrong registry">
    Package resolution is matched by npm scope. Confirm the package name's scope exactly matches a configured scoped registry (e.g. `@mycompany/utils` requires a `@mycompany` scoped registry). Packages whose scope has no dedicated registry (and all unscoped packages) resolve from the [default registry](#configure-the-default-registry). Scopes are case-insensitive and stored lowercase, so `@MyCompany` and `@mycompany` are treated as the same scope.
  </Accordion>

  <Accordion title="Can't change a scoped registry's scope">
    A scope is fixed once a scoped registry is saved. To move a registry to a different scope, delete the existing row and [add a new scoped registry](#add-a-scoped-registry) with the correct scope.
  </Accordion>

  <Accordion title="Native packages fail to build after disabling install scripts">
    Packages like `sharp`, `better-sqlite3`, and `node-canvas` require post-install scripts to compile native binaries. If you disabled **Allow packages to run post-install scripts**, these packages will fail to build.

    Either re-enable install scripts, or work with your security team to pre-build and publish these native packages as pre-compiled binaries in your registry.
  </Accordion>
</AccordionGroup>

## Related

* [Code Security overview](/admin/code-security/index)
* [CVE detection](/admin/code-security/supply-chain/cve-detection)
