Announcing elm-tooling CLI

elm-tooling CLI

elm-tooling is a command line program that manages your Elm tools. elm-tooling init creates elm-tooling.json, and elm-tooling install installs all tools specified in there in a fast and secure way. It’s a drop-in replacement for installing tools using npm.


For why to install locally, see When should I use elm-tooling to install tools? – it’s for the same reasons you’d use npm.

So what’s wrong with the npm based installers? It’s all about performance, user experience and security.

Let’s compare installing elm, elm-format and elm-json using npm and elm-tooling:

Metric npm elm-tooling
Number of packages 70 1
node_modules/ size 45 MB 120 KB
Installation time 9 s 2 s
Re-installation time 9 s 0.5 s
Processing Sequential Parallel
Download verification None SHA256

Working with Elm shouldn’t feel bloated. It should be snappy. It should be lightweight. It should be secure. And easy to use. elm-tooling is trying to do all that.

More details: Why install Elm tools using elm-tooling instead of npm?

How does elm-tooling work?

In elm-tooling.json you can specify your tools:

    "tools": {
        "elm": "0.19.1",
        "elm-format": "0.8.4"

elm-tooling install downloads the tools you’ve specified to ~/.elm/ (the place where Elm stores downloaded Elm packages) if they don’t exist already:

├── elm
│  └── 0.19.1
│     └── elm
└── elm-format
   └── 0.8.4
      └── elm-format

elm-tooling install then creates links in your local ./node_modules/.bin/ folder (use npx to run them):

./node_modules/.bin/elm -> ~/.elm/elm-tooling/elm/0.19.1/elm
./node_modules/.bin/elm-format -> ~/.elm/elm-tooling/elm-format/0.8.4/elm-format

More details: How does elm-tooling install work?

Getting started

Assuming you already have a package.json

  1. npm install --save-dev elm-tooling
  2. npx elm-tooling init
  3. npx elm-tooling install
  4. npx elm --help

Add "postinstall": "elm-tooling install" to your package.json to automatically run elm-tooling install after npm install.

Want more details? See Getting started on the website.

What’s next?

  • Keep tweaking the docs
  • Add elm-test-rs
  • Fix any issues reported!

Other than that elm-tooling feels complete!

Don’t forget to listen to the elm-radio episode about elm-tooling!


It requires npm? No thanks then, tools should be self-contained binaries.

Yeah, if you don’t want npm at all then the elm-tooling CLI is not the tool you’re looking for.

Interesting, if elm-tooling-cli had an equivalent to npx, able to manipulate the PATH env variable, it could be written as an independent binary I believe? We’d have etm instead of npm and etx instead of npx. And it could still create links to node_modules/.bin/ if a package.json is detected for compatibility with JS projects, otherwise use its own set of dirs (or no local dirs at all if etx can add an equivalent to node_modules/.bin/ to the path, but that would live in the elm home).

Yeah, I’ve been thinking of having something like elm-tooling run elm make src/Main.elm for executing tools with the correct PATH and stuff like you say. But as long as elm-tooling is written in Node.js there’s no need for it since we have npx.

Reasons for elm-tooling being written in/using Node.js include:

  • Editors and tools already support finding your executables in node_modules/.bin/.
  • It’s easy to install in CI – just npm ci. Compared to using curl, sha256sum, tar, chmod to download it from somewhere. Happy to hear better ideas!
  • Many use Node.js anyway currently. For elm-review, and/or for parcel/webpack/whatever to build the rest of your web app.

A cool thing is that anyone could write an alternative elm-tooling CLI in whatever language in a compatible way by following the elm-tooling.json spec.

  1. We’re using execa at the moment to resolve this, see GitHub - sindresorhus/execa: Process execution for humans which in turn seems to use GitHub - sindresorhus/npm-run-path: Get your PATH prepended with locally installed binaries
    I guess when we decide on another stadardized path to check before that, that should be possible, but will be code on our side.

  2. While I agree, that it’s easy, I would expect that only to be implemented once and just be a docker image, which people can use / copy the dockerfile from.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.