Skip to content

Instantly share code, notes, and snippets.

@sch
Last active September 30, 2018 15:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sch/8b845fd5ebaa418752c962f54b4d6b11 to your computer and use it in GitHub Desktop.
Save sch/8b845fd5ebaa418752c962f54b4d6b11 to your computer and use it in GitHub Desktop.
Elm as an NPM dependency

Sometimes you may want to have more than one version of Elm installed on your computer.

It could be that you're in the process of upgrading multiple projects, and you'd like to have one in 0.18 and another in 0.19. It could be you want to pin your version of Elm to something specific so you can be sure all the members of your team are using the same one. It could be you're relying on lots of Elm-related tooling, and you want to make sure you have the right combination for a specific project.

One option is to piggy-back on top of the Node Package Manager, and explicitly declare which version of Elm you'd like to use. The elm binary is wrapped up as a node module with a bit of metadata:

$ npm info elm@latest

elm@0.19.0-bugfix2 | BSD-3-Clause | deps: 1 | versions: 33
The Elm Platform: Binaries for the Elm programming language.
https://github.com/elm/compiler/tree/master/installers/npm

keywords: bin, binary, binaries, elm, elm-make, elm-package, elm-platform, elm-reactor, elm-repl, platform

bin: elm

...

You can tell NPM to download a specific version of Elm by creating a file called package.json:

{
  "private": true,
  "devDependencies": {
    "elm": "0.19.x"
  }
}

Node modules adhere to a thing called semantic versioning — specifying 0.19.x means "give me the latest bugfix version of Elm 0.19".

If you run npm install, this will create a directory called node_modules beside it with a ton of files. The elm binary is inside it at node_modules/.bin/elm. You can invoke it like this:

$ node_modules/.bin/elm --help
Hi, thank you for trying out Elm 0.19.0. I hope you like it!

...

Alternatively, you can call it using npx, which usually comes alongside your NPM installation. It will look for an executable in the current directory:

$ npx elm repl
---- Elm 0.19.0 ----------------------------------------------------------------
Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
--------------------------------------------------------------------------------
>

Things get really nice when you setup npm scripts — commands that can call into the executables directly. Consider this package.json:

{
  "private": true,
  "scripts": {
    "build": "elm make src/Main.elm --optimize --output build/main.js",
    "format": "elm-format src/Main.elm",
    "start": "elm reactor",
    "test": "elm-test"
  },
  "devDependencies": {
    "elm": "0.19.x",
    "elm-format": "0.8.x",
    "elm-test": "0.19.0-beta9"
  }
}

You can then run your script with npm run <script-name>:

$ npm run build

> elm make src/Main.elm --optimize --output build/main.js

Success! Compiled 1 module.


$ npm start

> elm reactor

Go to <http://localhost:8000> to see your project dashboard.

Come up with your own little automations like testing your app on a continuous integration platform, minifying your compiled javascript, handling publishing of an Elm library, integrating with a static site builder, whatever you want! The important thing is that you have reproducible dependencies for your project, and that will future-proof your developer setup 💅

{
"private": true,
"scripts": {
"build": "elm make src/Main.elm --optimize --output build/main.js",
"format": "elm-format --yes src/Main.elm",
"start": "elm reactor",
"test": "elm-test"
},
"devDependencies": {
"elm": "0.19.x",
"elm-format": "0.8.x",
"elm-test": "0.19.0-beta9"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment