Version: 2019.4
Accessing package assets
Resolution and conflict

Scoped package registries

A scoped registry allows you to use a custom registry where you can host your own packages, in addition to the Unity registry. This is the same concept that npm uses. Using scoped registries ensures that the Package Manager always maps a package to one and only one registry, guaranteeing a consistent result regardless of network conditions.

Some organizations work inside a closed network, which makes it difficult to access Unity’s own package registry. In these cases, the organization can set up their own package registry on a server inside their closed network. The network administrators can then periodically synchronize with Unity’s package registry to make sure the scoped registry has the latest set of packages available.

In some cases, developers want to provide their own custom modifications to standard Unity packages to their customers in a single, reliable location. Examples of these include creating custom toolbarA row of buttons and basic controls at the top of the Unity Editor that allows you to interact with the Editor in various ways (e.g. scaling, translation). More info
See in Glossary
or menu items for a Unity package, or extending the tools provided in a Unity package to interface better with their own custom package.

Custom package providers put their custom Unity packages on a package registry server. A package registry server is an application that keeps track of packages and provides a place to store them. A scoped registry communicates the location of the custom package registry server to Unity so that the user has a seamless experience where the custom package overrides the Unity package without the user having to manually install the set of custom packages.

This document explains how a package consumer can set up their Unity project to use an existing custom package registry server. If you are a package producer, see Sharing your package to find out which package registry servers are supported and links to information on how to set them up to use with scoped registries.

Note: If you are setting up a scoped registry that points to a package registry server with restricted access, you can configure Package Manager to pass your npm authentication token to the server. For more information, see Scoped registry authentication.

Setting up a scoped registry

To set up your scoped registries in your project manifestEach Unity project has a project manifest, which acts as an entry point for the Package Manager. This file must be available in the <project>/Packages directory. The Package Manager uses it to configure many things, including a list of dependencies for that project, as well as any package repository to query for packages. More info
See in Glossary
, use the scopedRegistries property, which takes an array of scoped registry configuration objects. Each object contains a name, a url location, and a list of scopes for each package name pattern you want to map to that scoped registry:

Property JSON Type Description
name String The scope name as it appears in the user interface. The Package Manager window displays this name in the package details view. For example, "name": "Tools".
url String The URL to the npm-compatible registry. For example, "url": "https://mycompany.example.com/tools-registry"
scopes Array of Strings Array of scopes that you can map to a package name, either as an exact match on the package name, or as a namespace.

For example, "scopes": [ "com.example", "com.example.tools.physics" ]

Note: This type of configuration assumes that packages follow the Reverse domain name notation. This ensures that com.unity is equivalent to com.unity.*.

When the Package Manager decides which registry to fetch a package from, it compares the package name to the scopes values and finds the registry whose scopes most closely match.

For example, in the project manifest below, there are two scoped registries, “Main” and “Tools”:

{
    "scopedRegistries": [
        {
            "name": "Main",
            "url": "https://example.com/registry",
            "scopes": [
                "com.example", "com.example.tools.physics"
            ]
        },
        {
            "name": "Tools",
            "url": "https://mycompany.example.com/tools-registry",
            "scopes": [
                "com.example.mycompany.tools"
            ]
        }
    ],
    "dependencies": {
        "com.unity.animation": "1.0.0",
        "com.example.mycompany.tools.animation": "1.0.0",
        "com.example.tools.physics": "1.0.0",
        "com.example.animation": "1.0.0"
    }
}

When the Package Manager looks up the com.example.animation package, it finds that the com.example.* namespace is the closest match to its name, and therefore fetches the package from the “Main” registry.

When the Package Manager looks up the com.example.tools.physics package, the “Tools” registry has a scope that exactly matches the package name.

When the Package Manager looks up the com.example.mycompany.tools.animation package, the Package Manager finds that the com.example.mycompany.tools.* namespace is the closest match to its name and therefore fetches the package from the “Tools” registry. Even though it also matches the “Main” scope, the com.example.* namespace is not as close a match.

When the Package Manager looks up the com.unity.animation package, the Package Manager doesn’t find a match in any of the scoped registries, and therefore fetches the package from the default registry.


Accessing package assets
Resolution and conflict