Use GitHub Packages to store font files as a private NPM package
GitHub Packages allow you to store up to 500 MB of NPM packages privately, for free.·267 views
I remember stumbling upon Kelly Harrop’s post, “Creating a fonts package,” some time last year. Intrigued, her idea marinated in my head for a while. Though I do share all of Kelly’s goals with the external font package, I had an additional goal not mentioned in her post: I wanted to make my font repo and NPM package private.
My reasoning here was twofold. I wanted to help protect the type foundry’s intellectual property, and I also wanted to comply with the EULAs I agreed to when I licensed a particular typeface.
Blanco — the serif typeface I use for body copy on this site1 — specifies in their EULA that the licensor cannot “store or use font files in a way that makes them available for use by any third party.” This, I think, rules out storing the font files as-is in a public GitHub repository.
As I put the finishing touches on this site’s latest design, I remembered Kelly’s post and decided to tweak her process for my private font packages.
Licensing issues aside, there are other reasons why you’d want to store font files — or any type of files, for that matter — in a separate, private NPM package:
- Confidential source code: Maybe you have code separate from your open-source project that you want to keep secret. In that case, turning a private repo into a GitHub Package you can
npm installis pretty handy.
- Reduce boilerplate: At work, I need to reach for the same typefaces on every single web project to adhere to our brand. Even though all of my work repos are private, it’s tedious doing the same setup tasks for every project. Maybe you need the same config files shared across a lot of projects, storing them in one source of truth is handy.
First, we’ll need to create the local directory that we’ll push to GitHub. I name mine after the typeface I will store in it, but you can name it whatever you want.
I then walk through the prompts to create a
package.json file. I don’t bother filling out the prompts, but you can if you want. Then, add the font files, an
index.css file, and a
README.md, if desired. In the end, your directory may look something like this:
│ ╰─ Blanco/
│ ╰─ woff2/
│ ├─ Blanco-Regular.woff2
│ ├─ Blanco-Italic.woff2
│ ├─ Blanco-Medium.woff2
│ ├─ Blanco-MediumItalic.woff2
│ ├─ Blanco-Bold.woff2
│ ├─ Blanco-BoldItalic.woff2
│ ├─ Blanco-ExtraBold.woff2
│ ╰─ Blanco-ExtraBoldItalic.woff2
I like to group my font files by file type, but you’re welcome to do what works best for you.
package.json may look something like this:
The lines I’ve commented are the crucial ones you will need to adapt to your environment.
Let’s take a look at the
Write as many
@font-face declarations as you need for your font files. Since I know I will be using the font’s kerning and ligatures features, I enable those in the
font-feature-settings property. I also specify the
unicode-range property to subset the font for the Latin alphabet.
Once you’ve set all of this up, go ahead and commit these to your GitHub repo. Make sure the name of the repo matches the name in your
Now that we have our GitHub repo set up, we need to configure a GitHub Personal Access Token (PAT) to allow us to push our package to GitHub Packages.
- To do this, go to your GitHub Settings.
- Click on the Developer settings tab.
- Then, click on Personal access tokens.
- In the Tokens (classic) tab, click Generate new token and give it a name. I called mine
Private GH registry, but name it whatever.
- Select the
- Once you’ve created the token, copy it to your clipboard. I recommend you stash it in a password manager or similar because you won’t be able to see it again.
Now we need to add our personal access token as a shell environment variable.
To configure bash or zsh to use GitHub Packages, we need to edit the
~/.zshenv file on our machine. My macOS machine uses zsh, so I will be adding a
~/.zshenv file (didn’t exist before). My Windows machine uses bash, so I edited the
~/.bashrc file there instead.
Here’s how we’ll do that:
- Go to the directory where your
.zshrcfile is stored, typically in your home directory. If you’re not sure, you can type the following in a new zsh terminal:
This will print out the directory of your
Once you’ve located the directory, you might not see the file right away. That’s because, by default, macOS hides files that start with a
.. To see the file, you can use the following keyboard shortcut: ⌘ + Shift + . — this will toggle the visibility of hidden files. You should see the
Create a new file (if not preexisting) called
.zshenvin the same directory.
In that file, add the following line:
GITHUB_TOKEN is the environment variable that will be referenced later, you can call it whatever you wish. Replace
GITHUB_PAT_TOKEN with the personal access token you created earlier. Save the file and close it.
Any programs you have running that use zsh will now have access to the
GITHUB_TOKEN environment variable (but you may need to restart them first).
- You can check that the environment variable is set by typing the following in a new zsh terminal:
- Go to the directory where your
.bashrcfile is stored, typically in your home directory. If you’re not sure, you can type the following in a new bash terminal:
Once you’ve located the directory, you might not see the file right away. That’s because, by default, Windows hides files that start with a
.. To see the file, you can click the View button in the File Explorer toolbar and then select Show → Hidden items. This will toggle the visibility of hidden files. You should see the
.bashrcfile and add the following line:
GITHUB_TOKEN is our environment variable that will be referenced later, you can call it whatever you wish. Replace
GITHUB_PAT_TOKEN with the token you copied earlier. Save the file and close it.
- You can check that the environment variable is set by typing the following in a new bash terminal:
Now that we have our environment variable set up, we can publish our package to GitHub Packages.
Go back to your font project directory and run the following command:
If everything was done correctly, it should publish your package to GitHub Packages. You’ll see an NPM package displayed on the sidebar in your GitHub repo. Sweet!
To use this package in your projects, you’ll first need to add an
.npmrc file to your project directory. This file will tell NPM to use GitHub Packages as the registry but only for the namespace that we’ll specify.
.npmrc file and add the following lines:
@johneatmon with your GitHub username, and replace
GITHUB_TOKEN if you named your environment variable something else.
We are telling NPM to only use GitHub Packages for packages that start with
@johneatmon (in this case, my username). This is important because we don’t want NPM to use GitHub Packages for all packages, just the ones we specify in this way.
Now, you can install the package in your project by running the following command:
To use the font in your project, you’ll need to import it in your CSS file. In my case, using Astro, I simply add the following line to my
<BaseHead /> component:
You may need to tailor this approach to your project, however.
All you need to do to deploy your application with private packages is add the
GITHUB_TOKEN to your .env variables.
You can safely commit
.npmrc to your project’s repo. It will not expose your GitHub PAT token because we kept it secret using a shell environment variable.
Note: When you do make changes to your fonts package, you’ll need to bump the version number in your
package.json file. Then, you can publish the new version by running the
npm publish command.
- “Creating a fonts package” by Kelly Harrop