Link Search Menu Expand Document

API reference

The elm-tooling npm package includes not only a CLI, but also an API that lets you:


Instead of using child_process.spawn, you can import the CLI and run it directly. That’s an easy way to make a cross-platform script.


import elmToolingCli from "elm-tooling";

  (exitCode) => {
    console.log("Exit", exitCode);
  (error) => {
    console.error("Unexpected error", error);

Here’s the full interface:

import type { Readable, Writable } from "stream";

type ReadStream = Readable & {
  isTTY: boolean;
  setRawMode: (mode: boolean) => void;

type WriteStream = Writable & {
  isTTY: boolean;

export default function elmToolingCli(
  args: Array<string>,
  options?: {
    cwd?: string;
    env?: Record<string, string | undefined>;
    stdin?: ReadStream;
    stdout?: WriteStream;
    stderr?: WriteStream;
): Promise<number>;

The default options use values from the process global.


This function lets npm packages depend on tools distributed as platform specific executables.

It makes sure that a tool choice exists on disk and then returns the absolute path to it so you can execute it.

  • Each user will only need to download each executable tool once per computer (rather than once per project).
  • If the user has the same tool in their elm-tooling.json, they will get maximum parallel downloading on clean installs.
export default function getExecutable(options: {
  name: string;
  version: string;
  cwd?: string;
  env?: Record<string, string | undefined>;
  onProgress: (percentage: number) => void;
}): Promise<string>;
  • name: The name of the tool you want. For example, "elm".

  • version: A ^ or ~ semver version range. The latest known version matching the range will be chosen. Note that the range has to start with ^ or ~ (or = if you really need an exact version) and must be followed by 3 dot-separated digits (unlike npm you can’t leave out any numbers). Example: "~0.2.8".

  • cwd: The current working directory. Needed in case ELM_HOME is set to a relative path. Defaults to process.cwd().

  • env: Available environment variables. ELM_HOME can be used to customize where tools will be downloaded. APPDATA is used on Windows to find the default download location. Defaults to process.env.

  • onProgress: This function is called repeatedly with a number (float) from 0.0 to 1.0 if the tool needs to be downloaded. You can use this to display a progress bar. Example numbers you might get:

  • Returns: A promise that resolves to the absolute path to the tool.

If you need several tools you can use Promise.all to download them all in parallel.


import getExecutable from "elm-tooling/getExecutable";
import * as child_process from "child_process";

  name: "elm-json",
  version: "~0.2.8",
  onProgress: (percentage) => {
    // `percentage` is a number from 0 to 1.
    // This is only called if the tool does not already exist on disk and needs
    // to be downloaded.
}).then((toolAbsolutePath) => {
  // `toolAbsolutePath` is the absolute path to the latest known elm-json 0.2.8 executable.
  // Standard Node.js `child_process.spawn` and `child_process.spawnSync` work
  // great for running the executable, even on Windows.
    child_process.spawnSync(toolAbsolutePath, ["--help"], { encoding: "utf8" })
}, console.error);