Publishing a project to npm
Tags: opensource
Published: 2021-11-27 07:45:07

## Introduction 📖

For the past three months, I have been working on my static site generator, adding features and fixing bugs as the project grows. With the recent implementation of [static analysis tooling](https://dev.to/mqnguyen/static-analysis-tooling-n55), [test suites](https://dev.to/mqnguyen/automated-testing-with-jest-4745), and [continuous integration](https://dev.to/mqnguyen/adding-continuous-integration-with-github-actions-33hm), I thought the project was finally ready for public use. 

## Preparing for release 🛠

### 1. Making the project callable by its name

To call the project directly, we have to map the entry file to its executable name, which we can do by adding the `main` and `bin` value to `package.json`:

```json
{
  "main": "src/index.js",
  "bin": {
    "mini-cli-ssg": "src/index.js"
  },
}
```

Inside `index.js`, we specifiy the environment of the executable by adding the following:

```js
#!/usr/bin/env node
```  

After that, we can register the binary (the `bin` value) globally by using `npm link`.

### 2. Testing the project locally

With `npm link`, we can now test our project locally on our machine before actually publishing it. Start by creating a temporary directory for testing anywhere on your machine (I recommend putting it on Desktop as it is easier to see). Then, inside the newly created directory, install the project using the following:

```bash
npm link mini-cli-ssg
```

After that, we can play around with the CLI by calling it by its name, passing in different arguments to ensure that all features are working.

### 3. Adding information to `package.json`

With the code tested and ready for publishing, it is time to prepare the `package.json`. So far, we already have the basic information covered, like the project name, description, author, etc. However, it is nice to include in more detail such as the project homepage or GitHub repository. We can do so by adding the following values to `package.json`:

```json
{
  "homepage": "<your GitHub repo/site here>",
  "repository": {
      "type": "git",
      "url": "git+<your GitHub repo here>"
  },
}
```

Additionally, we also need to ensure that the version number follows the semantic versioning rules. You can check out the full description of it [here](https://semver.org/), or read the shortened version in the [npm docs](https://docs.npmjs.com/about-semantic-versioning).

## Releasing to `npm` 💾

Here are the steps needed to publish the package:

- Create an account on [npmjs.com](https://www.npmjs.com/)
- Run the `npm login` command and input your information
- Run the `npm publish` command which will automatically publish it

## Receiving users' feedback

With the package published, I reached out to some of my friends via Discord, asking them to test my code using the installation and usage instructions included in the docs. To my surprise, there were actually some issues that managed to slip through while I was testing it locally:

- [#issue-23](https://github.com/mqnguyen5/mini-ssg/issues/23)
- [#issue-24](https://github.com/mqnguyen5/mini-ssg/issues/24)

After calling my friend and watching him run my package, I realized that I did not handle the file path properly. My classmate Duke also had a [blog post](https://dev.to/dukemanh/publish-a-cli-project-to-npm-10mc) about a problem similar to this, so I will leave the explanation to him. But in short, I had to change the path names leading to each of the `dist` and `assets` into absolute paths using `path.resolve()`.

## Conclusion

I can't believe I finally published my first ever package to npm. The experience was terrifying at first, but having someone to view and test your code gives you so many opportunities to learn from it. Additionally, it was satisfying seeing others were able to run your project successfully on their machines.