Uni­ty’s Pack­age Man­ag­er is so use­ful for dis­trib­ut­ing plugins/ code/ toolk­its that you use a lot, and it’s pos­si­ble to have your own pack­ages host­ed on GitHub.

I had to set this up for work recent­ly — I found two threads [1, 2] on Uni­ty’s forum, that helped, but were miss­ing infor­ma­tion that took me a while to work out. Below I’ll show what I did to get set­up with npm, pub­lish­ing pack­ages, and how to import them into Unity.

Installing npm

To pub­lish new pack­ages and update them, npm is required. npm comes with Node­js, down­load it from https://nodejs.org/en/ and select to install the addi­ton­al tools dur­ing instal­la­tion. Once it has fin­ished installing, reboot your machine.

To test npm has installed suc­cess­ful­ly open a com­mand prompt and type:

npm version

If installed and work­ing cor­rect­ly, you should see some­thing like this:


GitHub Personal Access Token (PAT)

So that npm can authen­ti­cate with GitHub and pub­lish pack­ages, we need to cre­ate a Per­son­al Access Token, click this link https://github.com/settings/tokens
(this is avail­able from pro­file pic­ture → Set­tings → Devel­op­er set­tings → Per­son­al access tokens)

Click the ‘Gen­er­ate new token’ button.

In the ‘Note’ textfield, type a rel­e­vant name for the token — this is best to be some­thing that eas­i­ly iden­ti­fies the device using this token.

In the ‘Select scopes’ sec­tion below, just tick ‘write:packages’, every­thing else required will auto­mat­i­cal­ly be select­ed too.

Then scroll down and click ‘Gen­er­ate token’.

The page will refresh and dis­play your PAT, at this point, keep this page open as you can­not see this token again once the page is closed.

(that auth token has been delet­ed and won’t work, don’t try and use it)

Setting up GitHub npm authentication

There’s some infor­ma­tion you’ll need at this point, I set this up for my work so I’m using the GitHub organ­i­sa­tion in this exam­ple, how­ev­er I believe your user­name should also work — from here on, @MyOrg is used to refer to the GitHub organ­i­sa­tion — replace any­where it says ‘myorg’ with your GitHub organ­i­sa­tion or username.

By default, all npm com­mands will point at the npm host­ed reg­istry url, we want to point to the GitHub pack­age reg­istry url.

Go to:
Win­dows: C:\Users\<yourusername>\
Mac: /Users/<your username>/
and look for a .npm­rc file, if one does­n’t already exist cre­ate it, and then open the file in a text editor.

Paste in the fol­low­ing two lines:

registry=https://npm.pkg.github.com/@MyOrg
//npm.pkg.github.com/:_authToken=

Go back to your brows­er and copy the PAT cre­at­ed in the step above, paste it after auth­To­ken= in the .npm­rc file. It should now look like this:

registry=https://npm.pkg.github.com/@MyOrg
//npm.pkg.github.com/:_authToken=0cd446905f2a9dbea98b6bf8b41535eabe93befe

(that auth token has been delet­ed and won’t work, don’t try and use it)

You can now save and close this file. It’s also now ok to close the brows­er win­dow where you cre­at­ed the PAT.


Create a GitHub repository

A repos­i­to­ry is required on GitHub to host your pacakges, cre­ate a new, emp­ty, repos­i­to­ry — you can have mul­ti­ple pack­ages in one repository.


Creating a package.json

This file is what every­thing uses for the data about a pack­age, it’s name, ver­sion, and a load of oth­er impor­tant information.

The first sec­tion to add is gen­er­al infor­ma­tion about the package.

{
    "name": "com.myorg.<packagename>",
    "displayName": "<packagename>",
    "version": "1.0.0",
    "unity": "2019.4",
    "description": "<description>",
    "keywords": [
        "key X",
        "key Y",
        "key Z"
    ],
    "category": "MyOrg",
    "author": {
        "name": "My Org",
        "email": "developers@myorg.co.uk",
        "url": "https://myorg.co.uk/"
    }
}

We need to an addi­tion­al prop­er­ty to point to the cor­rect reg­istry for the package.

"publishConfig": { 
    "registry": "https://npm.pkg.github.com/@MyOrg" 
}

The repos­i­to­ry prop­er­ty tells npm where to find the pack­age on the above reg­istry, which git repos­i­to­ry and a direc­to­ry the pack­age is in on that repos­i­to­ry. For the URL, enter the git URL for the repos­i­to­ry cre­at­ed above.

"repository": {
      "type": "git",
      "url": "ssh://git@github.com:MyOrg/MyRepository.git",
      "directory": "com.myorg.<packagename>"
}

A com­plete exam­ple package.json

{
    "name": "com.myorg.<packagename>",
    "displayName": "<packagename>",
    "version": "1.0.0",
    "unity": "2019.4",
    "description": "<description>",
    "keywords": [
        "key X",
        "key Y",
        "key Z"
    ],
    "category": "MyOrg",
    "author": {
        "name": "My Org",
        "email": "developers@myorg.co.uk",
        "url": "https://myorg.co.uk/"
    }
,
    "repository": {
      "type": "git",
      "url": "ssh://git@github.com:MyOrg/MyRepository.git",
      "directory": "com.myorg.<packagename>"
    },
    "publishConfig": { 
        "registry": "https://npm.pkg.github.com/@MyOrg" 
    }
}

Unity package setup

Uni­ty requires a bit of set­up to be able to access pack­ages on GitHub, for­tu­nate­ly this is only required once per machine. Every­one on your team, that uses the Uni­ty project, will be required to do this step next step of cre­at­ing the upm con­fig, even the artists.

upm config

Go to:
Win­dows: C:\Users\<yourusername>\
Mac: /Users/<your username>/
and look for a .upmconfig.toml file, if one does­n’t already exist cre­ate it, and then open the file in a text editor.

Paste the fol­low­ing into this file:

[npmAuth."https://npm.pkg.github.com/@MyOrg"]
token = "<PAT created on Github>"
email = "<your email>"
alwaysAuth = true

The token is the same PAT cre­at­ed for the npm authen­ti­ca­tion, you can grab it from your .npm­rc file. Use your work email address as your email. Now save and close.

Adding a Scoped Registry to Unity

In Uni­ty open the ‘Project Set­tings’ and go to ‘Pack­age Man­ag­er’, enter the fol­low­ing details into the avail­able fields:
Name: MyOrg Toolk­it
URL: https://npm.pkg.github.com/@MyOrg
Scope(s): com.myorg

Notice that the scope is the same as the package.json cre­at­ed above, you don’t want to add any addi­tion­al bits to this text — it will see every pack­age with­in the same scope at the git repo/registry we’re point­ing it at.

Unfor­tu­nate­ly, Uni­ty won’t dis­play any of these pack­ages in the Pack­age Man­ag­er, so they require man­u­al­ly adding to the project manifest.json locat­ed in <UnityProject>/Packages/

Open the manifest.json and add the pack­ages with the oth­er dependencies:

"dependencies": {
    "com.myorg.mypackage01": "1.0.1",
    "com.myorg.mypackage02": "1.0.0",
    "com.myorg.mypackage03": "1.0.0",
    "com.myorg.mypackage04": "1.0.0",
    "com.unity.cinemachine": "2.3.4",
…
}

Save, and return to Uni­ty, the pack­ages will get import­ed and be vis­i­ble in the Pack­age Man­ag­er. They’ll also show that updates are avail­able and can be updat­ed via the Pack­age Man­ag­er now.

Note:

If you scroll down to the bot­tom of the manifest.json, you’ll notice that the scoped reg­is­tery we added in Uni­ty appears here, and looks like this:

"scopedRegistries": [
    {
      "name": "MyOrg Toolkit",
      "url": "https://npm.pkg.github.com/@MyOrg",
      "scopes": [
        "com.myorg"
      ]
    }
  ]

Console errors

Now when you open the Pack­age Man­ag­er, you’ll notice some con­sole errors appear. These can be ignored — (I believe) it’s a lim­i­ta­tion of the Uni­ty Pack­age Man­ag­er not be able to search through cus­tom scoped reg­istries, and returns an error.