DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Create Your First Github Package
Dale Nguyen
Dale Nguyen

Posted on • Updated on • Originally published at dalenguyen.me

Create Your First Github Package

Github introduced their Github Package Registry since May 2019 - a package management service, just like NPM packages. That means you can manage private or public packages next to your source code.

At the moment when I write this article, you still have to Sign up for the beta in order to try this new service.

Here are the steps that you can follow to create your first Github Package.

Step 1: create a Personal Access Tokens

Login to your Github account > Settings > Developer settings

Alt Text

Step 2: log in to npm.pkg.github.com

dnguyen:~ dalenguyen$ npm login --registry=https://npm.pkg.github.com
Username: GitHub-username
Password: your-personal-access-token
Email: (this IS public) your-email@example.com
Logged in as dalenguyen on https://npm.pkg.github.com/.
Enter fullscreen mode Exit fullscreen mode

Step 3: prepare your source code

I already created a TypeScript Package Starter. You can clone it from Github.

git clone https://github.com/dalenguyen/typescript-package-starter.git

Enter fullscreen mode Exit fullscreen mode

Here is the project structure:

dist 
--index.js
src
--index.ts
test
--index.spec.ts
Enter fullscreen mode Exit fullscreen mode

This package has only one simple function: helloWorld

export const helloWorld = () => 'Howdy!'

Enter fullscreen mode Exit fullscreen mode

In order to publish your package to Github Package Registery, you need to add publishConfig. Otherwise, it will publish the package to the NPM Package Registry.

{
  "name": "typescript-package-starter",
  "version": "1.0.0",
  "description": "TypeScript boilerplate for NPM or Github Packages",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "test": "mocha --timeout 60000 --exit -r ts-node/register test/**/*.spec.ts",
    "build": "tsc",
    "deploy": "npm publish"
  },
  "author": "Dale Nguyen",
  "license": "ISC",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/dalenguyen/typescript-package-starter.git"
  },
  .........................
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/@dalenguyen"
  }
}
Enter fullscreen mode Exit fullscreen mode

This will end up creating a package name: @dalenguyen/typescript-package-starter. You need to replace the username in the package.json when you work with your own package.

And thanks to Alex β€” my coworker β€” by adding the repository, you have the ability to publish multiple packages to the same GitHub repository.

Step 4: push your project to Github repo

After you have your code ready. Push it to your github repo. You have to create your repo from Github.com.

git init
git add .
git commit -m "Create first github package"
git push origin master
Enter fullscreen mode Exit fullscreen mode

Step 6: publish your first Github package

Run the test, make sure that everything works

npm test
Enter fullscreen mode Exit fullscreen mode

Deploy your first Github package

npm run build && npm deploy
Enter fullscreen mode Exit fullscreen mode

and VoilΓ 

Alt Text

Step 7: Try to install your first Github package

Before that, you need to create a .npmrc file

// .npmrc
@your-username:registry=https://npm.pkg.github.com
Enter fullscreen mode Exit fullscreen mode

Then install your package:

dalenguyen$ npm i @dalenguyen/typescript-package-starter

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN github-packages@1.0.0 No repository field.
+ typescript-package-starter@1.0.0 (as @dalenguyen/typescript-package-starter)
added 1 package from 1 contributor and removed 6 packages in 2.375s
Enter fullscreen mode Exit fullscreen mode

Step 8: Test your new created package

// index.js
const starter = require('@dalenguyen/typescript-package-starter')
console.log(starter.helloWorld())
Enter fullscreen mode Exit fullscreen mode

Run the index.js file

dalenguyen$ node index.js
Howdy!
Enter fullscreen mode Exit fullscreen mode

Now you know how to create and publish your first Github package. In the next post, I will try to add CI/CD in order to publish the package automatically with Github Actions.

Top comments (11)

Collapse
 
demonkart profile image
Alan P. C. Silva

Hi! Great article :)

I am facing some issues when trying to fetch a specific version of my published package using Yarn.
I have created a repo based on your template: and I am adding this project as a dependency on another.
It works just fine after configuring the registry on .npmrc file. However, when I publish a new version of the package, it does not get updated when I run yarn on their dependent projects.

So, I tried to update the version manually in the package.json file with
"@demonkart/shared-deps-poc": "1.0.1", even though my package is at v1.0.2 right now.

If I run npm install then it works. If I run yarn it fails with the following error:

An unexpected error occurred: "https://npm.pkg.github.com/download/@demonkart/shared-deps-poc/1.0.1/3e9396a9012235c5bced735c282dc2ffcd11c9e7ce1889ace5b8703bb1c9ae48: Request failed \"401 Unauthorized\""

I have logged into github npm registry and this project is public... Any idea of what might be happening? 'x)

Thanks

Collapse
 
dalenguyen profile image
Dale Nguyen

Can you try 'yarn cache clean' and update it again?

Collapse
 
demonkart profile image
Alan P. C. Silva

Hi there. I tried it and still not working with yarn

Thread Thread
 
dalenguyen profile image
Dale Nguyen

I don't know what happens yet. You can use npm for now. Or create a public repo so people can help to debug it.

Thread Thread
 
demonkart profile image
Alan P. C. Silva

Hi there. I found a way searching through github yarn repo issues. It is not well documented yet and seems a little hacky, but it works.

I have added a section in the repo mentioned on how to make it work with yarn

github.com/DemonKart/shared-deps-p...

I hope it helps others like you helped me :)

Collapse
 
davestewart profile image
Dave Stewart • Edited on

Hey Dale,

Thanks so much for this tutorial! It's certainly got me the closest to publishing and installing a private package.

However, when I try this, my package – and your package – is installed unscoped.

It installs under node_modules/typescript-package-starter not node_modules/@dalenguyen/typescript-package-starter and you need to descope the require as well:

const starter = require('typescript-package-starter')
console.log(starter.helloWorld())

This is the same experience I have had with my own package.

When add the @org-name/ in the package.json name as per normal NPM packages...

{
  "name": "@dalenguyen/typescript-package-starter",
  ...
}

...the install command under GitHub packages ends up including the scope twice, so for your package would be:

npm install @dalenguyen/@dalenguyen/typescript-package-starter@1.0.0

I guess in theory the de-scoping I am experiencing should not be a problem – because the code works – but it's strange considering it could potentially clash with an unscoped package of the same name.

Any ideas?

P.S. You can color-code your codeblocks by appending the language name to codeblock backticks, i.e. '''js

Collapse
 
dalenguyen profile image
Dale Nguyen • Edited on

Thank Dave for the question. I just tried my package. It installs under node_modules/@dalenguyen

Can you fork my project, modify and deploy to your Github package?

dev-to-uploads.s3.amazonaws.com/i/...

Collapse
 
davestewart profile image
Dave Stewart

Good plan. Let me try that

Thread Thread
 
dalenguyen profile image
Dale Nguyen

Let me know if it works. And can you help to remove the .npmrc file? The token is invalid, but it is better to remove it though. Thanks,

Collapse
 
omgdadps profile image
OMGdaDPS

Hey so I get to the point where I have to run the "git push origin master" command, but after entering my credentials and token, I get this:
remote: Permission to dalenguyen/typescript-package-starter.git denied to OMGdaDPS.
fatal: unable to access 'github.com/dalenguyen/typescript-p... The requested URL returned error: 403

Collapse
 
dalenguyen profile image
Dale Nguyen

Hi @omgdadps , you need to create your own git repo, and replace my username with yours. Otherwise, it will push to my repo which you don't have permission to.

11 Tips That Make You a Better Typescript Programmer

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!