import { Callout } from "nextra-theme-docs";

# Hosting the Bundler

<Callout>
  You can also host the bundler by yourself, all necessary files are in the
  `sandpack` folder.
</Callout>

If you want to host the bundler yourself, you will need to do a few things.

- The bundler is part of the codesandbox-client codebase: https://github.com/codesandbox/codesandbox-client
- Clone the codesandbox-client and install the dependencies in the root folder (`yarn install`).
- `yarn build:deps` to build some of the packages lerna needs for internal links.
- create your instance of sandpack with `yarn build:sandpack`.

This creates a `www` folder in the root of `codesandbox-client`. That `www` folder is the
sandpack folder sandpack-client connects to on `{version}-sandpack.codesandbox.io`.
Once you have this hosted on your end you can pass `bundlerURL` when calling:

```js
new SandpackClient(iframe, sandboxInfo, {
  bundlerURL: "https://your-hosted-version",
});
```

or, if you use sandpack-react, you can bundlerURL in the `options` of the Sandpack preset.

### Why

There are few reasons for hosting the bundler like this, as opposed to having it exported as library code.

#### Security

The bundler evaluates and transpiles all files in an iframe under a different
subdomain. This is important, because it prevents attackers from tampering with
cookies of the host domain when evaluating code.

#### Performance

We heavily make use of Web Workers for transpilations. Almost all our
transpilation happens in web workers, and there is no easy way yet to bundle
this in a library.

#### Bundle Size

Another reason to host the bundler externally is because of code splitting: we
split all our transpilers away and load them on-demand. If a user doesn't use
`sass` we won't load the transpiler. This wouldn't be possible if we would give
one big JS file as the library.

#### Offline Support

We use Service Workers to download all transpilers in the background, so the
next time a user visits your website they don't have to download the bundler
anymore and it can be used offline. This is possible because we host the service
worker externally.

## Self-host private packages

<br />

<big>
  The custom private NPM registry allows Sandpack instances to retrieve private
  NPM packages from your own registry. This option requires running a third
  service (Node.js server) and configuring your Sandpack provider to consume
  these dependencies from another registry, not the public ones.
</big>

**You'll need:**

- Host a Node.js server, which will run registry proxy;
- GitHub/NPM authentication token with read access;

### Self-host the proxy

We recommend hosting a service that allows you to proxy your private packages from a registry (GitHub/Npm/your own) to a new one, which would make the packages available through another URL.
As Sandpack bundles everything in-browser, it needs to find a way to connect to the registry which provides the project dependencies.
First, Sandpack will try to fetch all dependencies from public registries, for example, `react` or `redux`. Then you can let Sandpack know which dependencies (or scoped dependencies) should be fetched from a different registry. For example, your custom registry.

#### Our recommendation

Suppose you don't already have a public registry, we recommend using [Verdaccio](https://verdaccio.org/). An open-source project that creates a private registry and can proxy other registries, such as GitHub and Npm.
You can find examples of how to use the [examples folder](https://github.com/codesandbox/sandpack/tree/main/examples) in the main repository.

### Sandpack configuration

Once the proxy is running and configured, you need to set some options in your Sandpack context:

```jsx
<Sandpack
  customSetup={{
    dependencies: { "@codesandbox/test-package": "1.0.5" },
    npmRegistries: [
      {
        enabledScopes: ["@codesandbox"],
        limitToScopes: true,
        registryUrl: "PROXY_URL",
      },
    ],
  }}
  files={{
    "/App.js": `import { Button } from "@codesandbox/test-package"
export default function App() {
  return (
    <div>
      <Button>I'm a private Package</Button>
    </div>
  )
}
`,
  }}
  template="react"
/>
```

### Security

It's essential to keep the information and tokens of the npm registry private! By using this method, it's best to keep in mind that it could expose all private packages in your account. Be careful where and how this proxy will be used. Make sure to use authentication tokens with **read-only access**.

It's also possible to expose only specific packages. If the custom scopes are `@scope/package-name` instead of `@scope/*`, it will only expose that particular package. You can even do something like `@scope/design-system*` to expose all packages of the design system.