Consuming Node projects for Nix users

Recently, I wrote a formatting tool for Nix that I wanted to use to format some derivations automatically. And while the project is written in PureScript, there is nothing PureScript about how this project is consumed, as it is structured as a normal Node.js project. This project will try to show you how Node.js projects are structured how you can easily consume the format-nix project in one of two ways.

## Project structure

Any Node project has one actual essential file: `package.json`. For most projects that can be consumed as an application, there are only two fields you need to be concerned with:

```js
{
  // ...

  // if this package is consumed as a binary, what executables are there, and what do they run?
  "bin": {
    "format-nix": "bin/index.js"
  },

  // ...

  // what dependencies does this project have?
  "dependencies": {
    "tree-sitter": "^0.14.0",
    "tree-sitter-nix": "github:cstrahan/tree-sitter-nix#c885d29d567d5d99c0774da7ee20a575a0b733f4"
  },

  // ...
}
```

The other fields in the package.json file are not very important for now.

## `bin["format-nix"] = "bin/index.js"`

This means that our project has a `bin` directory that has at least a `index.js`. Indeed, our project has even two files under bin:

```
$ fd . bin/
bin/index.js
bin/output.js
```

And `index.js` actually simply requires the output file and runs it:

```js
#!/usr/bin/env node
require('./output.js');
```

Indeed, `output.js` is produced by our PureScript sources, but as a purely JavaScript program generated by PureScript, we do not need to compile anything to consume this project. **This means we do not need to install PureScript tooling.** This is constantly a point of confusion, but it's the same as the HTML pages you see in a blog -- you don't need to execute a bunch of Ruby scripts to look at someone's Jekyll-based blog.

## Consuming the project with `npm`

If you choose to use `npm` to consume `npm` projects, that can be done quite easily. If you don't regularly use npm, make sure your prefix is set correctly:

```
$ npm get prefix
/home/your-user/.npm
```

If this is `/usr/local` or some other ridiculous location that you do not own, fix this by running `npm set prefix ~/.npm` or by writing `~/.npmrc` directly as `prefix=/home/your-user/.npm`. **Never use sudo with npm.**

If you have a proper setup, then simply running `npm link` will install this project locally for consumption:

```
$ npm link

# npm installation details

/home/your-user/.npm/bin/format-nix -> /home/your-user/.npm/lib/node_modules/@justinwoo/format-nix/bin/index.js
/home/your-user/.npm/lib/node_modules/@justinwoo/format-nix -> /your/local/clone/of/format-nix
```

Now you can use `format-nix` as you wish.

## Consuming the project with `nix`

If you want to consume the project with `nix`, that can be accomplished easily. First, prefetch the git repository information:

```
$ prefetch-github -owner justinwoo -repo format-nix
{
  owner = "justinwoo";
  repo = "format-nix";
  rev = "acfb588e0e8cfd5d34a94c460ae5d27462d20b76";
  sha256 = "14rgf8rm2mmqz0380lmq1rra0k7k7n5v1fd0ysz085kil0mrwqrb";
}
```

With this information, you can prepare a derivation in any way you please. For example, we could simply create a `default.nix` file in an empty directory:

```nix
{ pkgs ? import <nixpkgs> {} }:

import (pkgs.fetchFromGitHub {
  owner = "justinwoo";
  repo = "format-nix";
  rev = "acfb588e0e8cfd5d34a94c460ae5d27462d20b76";
  sha256 = "14rgf8rm2mmqz0380lmq1rra0k7k7n5v1fd0ysz085kil0mrwqrb";
}) {
  inherit pkgs;
}
```

Once you have this, you can build this derivation and use it in any way you consume other projects. See <https://github.com/justinwoo/consume-format-nix-test>.

## Conclusion

I hope this post has shown you

* Where to look inside of Node projects you might want to consume
* How to install Node projects in some various ways
* How to install format-nix
* How format-nix does not require you to install any PureScript tooling

## Links

* format-nix: <https://github.com/justinwoo/format-nix>

## P.S.

I do not have constructive things to say about efforts to write Nix formatters in other ways, so please refrain from asking me about them.