Free private npm package using GitHub
Tags: webdev, github
Published: 2021-05-06 15:37:19

Sharing logic between more than one application is crucial for creating scalable architecture. We can move some logic, UI components into a separate package. Next, this package can be shared between different applications. When we don’t want to open source your code we can use [Github packages](https://github.com/features/packages).

_Don’t get me wrong. There is nothing wrong with open-sourcing your work. Probably anyone notices that you open-sourced your UI components. But if in your project it’s prohibited in this article I will cover how to make a private package._

***

![](https://cdn-images-1.medium.com/max/1600/1*yai9SB29FLJAL0kEO02oXA.png)

I’m making [Bookmarkly - best bookmarks manager](https://bookmarkly.app/), it uses ML models to manage and organize your bookmarks. Helps boost your productivity, and you don’t need to worry about the mess when you are saving links.  
I’m using Github packages to distribute bookmarkly machine learning models for multiple environments. Check application on [https://bookmarkly.app/](https://bookmarkly.app/ "https://bookmarkly.app/")

***

#### Github Packages overview

Github provides free options in offering package hosting. There are two main constraints:

* First is available space for packages or packages. You can use only 500MB of storage.
* The second is “Data transfer out outside of Actions” and it’s 1GB.  
  This means that downloading packages for local development is limited to 1GB bandwidth per month.  
  _Downloading the package in Github Actions doesn’t count._

### Preparing

You can make it in the monorepo repository, it will work just fine. In our case, we make a new repository, just for the GitHub package.

#### Codebase

First, we need to run `npm init` to create a package.json file. What’s important here you need to make a scoped package name. Scoped package names start with “@” and contain your username and package name. In my case is “@perfect7m/package-name”. [Github only supports only scoped packages](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#publishing-a-package). The scope should be the username or organization name where the repository exists.

I‘m using [Microbundle](https://github.com/developit/microbundle) for creating package files in different formats, for server and browser. It’s made by [Developit](https://twitter.com/_developit) creator of [PreactJS](https://preactjs.com/). I wrote recently an article about [why preact is worth checking in 2021](https://marcin.page/posts/is-preact-worth-checking-in-2021/). Follow the installation instruction in the Microbundle repository.  
Feel free to use Webpack, Rollup, or any bundler that works for you.

The last thing that needs to change is to add `publishConfig` in package.json. Everything setup should look like this:

```json
{
  "name": "@perfect7m/package-name",
  "version": "0.1.0",
  "description": "",
  "source": "src/package-name.js",
  "main": "dist/package-name.js",
  "exports": "./dist/package-name.modern.js",
  "module": "dist/package-name.module.js",
  "unpkg": "dist/package-name.umd.js",
  "scripts": {
    "build": "microbundle",
    "dev": "microbundle watch"
  },
  "publishConfig": {
    "registry":"https://npm.pkg.github.com"
  },
  "author": "Perfect7M",
  "license": "MIT",
  "devDependencies": {
    "microbundle": "^0.13.0"
  }
}
```

When you create `package-name.js` in `/src` directory and run `npm run build` you get all the needed files built.

#### Package

To publish the package we need to create a `.npmrc` file where we will keep access to the Github npm registry. Add the following to your `.npmrc` file:

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

* _TOKEN_ is your Github Personal Token. You can obtain it from [https://github.com/settings/tokens](https://github.com/settings/tokens "https://github.com/settings/tokens").  
  **Make sure that** `write:packages` **permission is checked!**
* _OWNER_ is your Github username.

**Create** `.gitignore` **file in your project and add there** `.npmrc`**. Don’t push it with your code. It’s dangerous to show unauthorized people tokens, this token can uploads packages on your behalf!**

Also, consider creating

### Publishing

When we want to publish a package to the Github npm registry we need to authorize ourselves. To make that happen you need to run the following command and provide data:

    npm login --scope=@OWNER --registry=https://npm.pkg.github.com
    
    > Username: GITHUB USERNAME
    > Password: GITHUB PERSONAL TOKEN
    > Email: GITHUB EMAIL ADDRESS

When you are logged in you can submit the package to the registry. To do that run `npm publish` and see the result. You should see this with your package data.

![](https://cdn-images-1.medium.com/max/1600/1*SB7ZeOhfQEZNt69VkHDgdA.png)

### Installing

In every repository, we want to use this package we need to add `.npmrc`. By default, npm is configured only to search for packages in the official package registry.

    @OWNER:registry=https://npm.pkg.github.com

As previously, _OWNER_ is your Github username or organization.

Then you need to run as normal install command:

```bash
npm install @OWNER/package-name
```

That’s it. You can use your package code in the project codebase. It’s up to you how you set up your package, what you are exporting, and which platform you support.

### Summary

That’s how you can set up a small private package. For medium-size organizations or personal projects, this is a great option to distribute codebases. You can read more in [official documentation](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry), Github packages are not limited to npm but support others packages registry for Docker or Gradle.