# Install nodejs package to env

**URL:** https://discourse.flox.dev/t/install-nodejs-package-to-env/714
**Category:** Help
**Created:** [March 30, 2023, 7:07am UTC](https://discourse.flox.dev/t/install-nodejs-package-to-env/714 "2023-03-30T07:07:19Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![tom](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.flox.dev/tom/32/573_2.png) [@tom](https://discourse.flox.dev/u/tom)
#### Post date: [March 30, 2023, 7:07am UTC](https://discourse.flox.dev/t/install-nodejs-package-to-env/714/1 "2023-03-30T07:07:19Z")

</div>

My dev env uses several tools installed from [npmjs.com](http://npmjs.com) . How do I install a nodejs module ‘globally’ with flox? - they do not show up in search.

---

<div class="post-metadata">

### Author: ![aameen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.flox.dev/aameen/32/564_2.png) [@aameen](https://discourse.flox.dev/u/aameen)
#### Post date: [March 30, 2023, 3:24pm UTC](https://discourse.flox.dev/t/install-nodejs-package-to-env/714/2 "2023-03-30T15:24:52Z")

</div>

Howdy, this is one that I actually have a lot of experience with, so I’m sure I can help you out.

I’d like to gather a bit of context first so I can recommend the appropriate approach.

1. Which module(s) are you interested in installing?
2. Are you aiming to use these module(s) for their executables, for `require( '<NAME>' );`, or both?
3. Do you automatic updates from a `package.json`, `package-lock.json`, `yarn.lock`, etc, or are your updates infrequent enough that you could manually trigger a “regeneration” script?
4. Are you consuming these modules in a project ( `flox.nix` ), or a “global” environment?
5. Are you comfortable writing Nix expressions?

The “simplest” approach that doesn’t require any `nix` experience is simply to install `npm` or `yarn` using `flox`, and running something like:

```auto
envName="${FLOX_ACTIVE_ENVIRONMENTS##:*}";
export NPM_CONFIG_PREFIX="/tmp/${envName}-npm";
mkdir -p "$NPM_CONFIG_PREFIX";
export NODE_PATH="$NPM_CONFIG_PREFIX/lib/node_modules${NODE_PATH:+:$NODE_PATH}";
export PATH="$PATH:$NPM_CONFIG_PREFIX/bin";

npm install -g lodash@4.17.21;
npm install -g pacote@13.3.0;
# ...

```

While this process certainly isn’t ideal, it would provide an isolated env associated with your workspace that is reproducible.

For an “improved” experience you could create `nix` recipes and ( optionally ) use `flox publish` to maintain a catalog of globally installable modules. There’s a variety of useful tools which largely automate this process ( one that I authored is here: [GitHub - aakropotkin/floco: Using Nix to put NPM and Yarn in a coffin](https://github.com/aakropotkin/floco) ). Knowing more about the “context” questions above would help me make recommendations.

---

<div class="post-metadata">

### Author: ![tom](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.flox.dev/tom/32/573_2.png) [@tom](https://discourse.flox.dev/u/tom)
#### Post date: [March 31, 2023, 2:35am UTC](https://discourse.flox.dev/t/install-nodejs-package-to-env/714/3 "2023-03-31T02:35:11Z")

</div>

> 1. Which module(s) are you interested in installing?

@moonrepo/cli  
prettier-package-json

> 1. Are you aiming to use these module(s) for their executables, for `require( '<NAME>' );`, or both?

The clis. Any libs would not need to be in PATH or installed without pnpm and am not looking at replacing pnpm with nix at the moment. Moon is the only one I really need to be in PATH rather than installed in the local node\_modules. I could invoke it with run scripts or cargo-make or something but figured I should solve this question before getting too deep into flox or nix.

> 1. Do you automatic updates from a `package.json`, `package-lock.json`, `yarn.lock`, etc, or are your updates infrequent enough that you could manually trigger a “regeneration” script?

Moonrepo changes quite a bit. I havnt used [renovate’s new nix suppor](https://github.com/renovatebot/renovate/tree/b53b8bca6b7c5c3c8faf777287b971e47a6732bf/lib/modules/manager/nix)t yet but plan too.is a quite different question.

> 1. Are you consuming these modules in a project ( `flox.nix` ), or a “global” environment?

Not sure what global means here. In the devshell path.

> 1. Are you comfortable writing Nix expressions?

Yes, but competent is a quite different question.

---

<div class="post-metadata">

### Author: ![aameen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.flox.dev/aameen/32/564_2.png) [@aameen](https://discourse.flox.dev/u/aameen)
#### Post date: [April 6, 2023, 8:33pm UTC](https://discourse.flox.dev/t/install-nodejs-package-to-env/714/4 "2023-04-06T20:33:28Z")

</div>

Alright so the fact that these are needed as CLI tools in `PATH` rather than members of a `node_modules/` directory makes things significantly easier.

Essentially the process will be to package those two tools up using a `node` to `nix` translation tool to create a [custom package](https://floxdev.com/docs/custom-packages/) that `flox` can use.

I’ll use `moon` as an example to package, which you can follow along with. I chose the translator `floco`, but `node2nix` or other translators would work fine as well.

Here’s the process from scratch in an empty project area, you could perform roughly the same steps in an existing `flox` project ( probably edit `flake.nix` manually for an existing project ).

```console
$ mkdir -p moon;
$ cd moon;
$ git init;

# Based on the usual `flox init -t project' template:
# Add `floco' to our inputs, and set a new description
$ cat <<'EOF' > flake.nix
{
  description = "moon command line and core system";

  inputs.flox-floxpkgs.url = "github:flox/floxpkgs";
  inputs.floco.url = "github:aakropotkin/floco";

  outputs = args @ {flox-floxpkgs, ...}: flox-floxpkgs.project args (_: {});
}
EOF

$ mkdir -p pkgs/moon;
$ pushd pkgs/moon;
# Generate a `nix' build for the package.
$ flox nix run 'github:aakropotkin/floco#fromRegistry' -- @moonrepo/cli@1.1.1;

# Adapt some boilerplate taken from `floco' "registry" project template to play
# nicely with `flox':
$ cat <<'EOF' > ./default.nix
{
  lib
, inputs
, system
}: let
  ident = "@moonrepo/cli";
  version = "1.1.1";
  fmod = lib.evalModules {
    modules = [
      inputs.floco.nixosModules.floco
      { config.floco.settings = { inherit system; }; }
      ./pdefs.nix
      {
        config.floco.packages.${ident}.${version} = {
          # Force copying of tree during `install' so we can copy binaries.
          installed.override.copyTree = true;
          # This package has no runtime deps, the declared dependencies are only
          # required during installation, so we can drop them.
          trees.global = null;
        };
      }
    ];
  };
in fmod.config.floco.packages.${ident}.${version}.global // {
  meta.description = "moon command line and core system";
  meta.mainProgram = "moon";
  meta.license = lib.getLicenseFromSpdxId "MIT";
}
EOF

$ popd;
$ git add ./flake.nix ./pkgs;
$ flox build moon;
$ ls ./result/bin;
$ ls ./result/lib/node_modules/@moonrepo/cli/;

```

Because `moon` has an “install script” we added a few extra lines to a `default.nix` file, but for `prettier` and any other package that doesn’t have a `postinstall` script you could drop lines 14-22.

This is essentially similar to packaging any `node` project using `nix`, the main difference is that `flox` expects a standardized file hierarchy, so you’ll want to place any `default.nix` files under `./pkgs/<NAME>/default.nix`.

Ideally we’ll get a more streamlined process for creating `node` packages, but for now this should get you up and running. Let me know if there’s anything else I can help with.
