Skip to content

jclem/konk

Repository files navigation

Konk

Konk runs a series of commands serially or concurrently. It is especially well-suited to running multiple npm scripts.

Why?

There are two npm packages I frequently already use for running npm scripts serially or concurrently: npm-run-all and concurrently. I built konk because I wanted something that could run serially and concurrently and did not need to be installed as an npm package (note, however, that konk can be installed from npm). In addition, I wanted to be able to use the same command line interface to run processes defined in a Procfile. Finally, I have always been curious how to build such a command line interface, so this is also a learning exercise for me.

There are currently feature gaps between npm-run-all and concurrently, but I am working to fill them when I have time.

Installation

Install via Homebrew:

$ brew install jclem/tap/konk

Or, use or install directly from npm:

$ npx konk      # Run from npm
$ npm i -g konk # Install from npm

Usage

Run Commands: konk run

Konk can run an arbitrary list of commands passed to it, either serially or concurrently.

Run some commands serially, one after the other. They will be run in the order they're presented in the command line interface.

$ konk run s 'echo hello' 'echo world'
[0] hello
[1] world

Run some commands concurrently (notice the interleaved output).

$ konk run c ls ls
[1] README.md
[1] bin
[1] go.mod
[1] go.sum
[0] README.md
[1] konk
[1] main.go
[0] bin
[0] go.mod
[0] go.sum
[0] konk
[0] main.go

Use the -n/--npm flag to easily run scripts in your package.json. For example, given these scripts:

{
  "scripts": {
    "check:build": "tsc --noEmit",
    "check:format": "prettier --loglevel warn --check .",
    "check:lint": "eslint ."
  }
}

You can run all three concurrently with with -n/--npm flags:

$ konk run c --npm 'check:format' --npm 'check:lint' --npm 'check:types'
[2]
[2] > check:lint
[2] > eslint .
[2]
[1]
[1] > check:format
[0]
[0] > check:build
[0] > tsc --noEmit
[0]
[1] > prettier --loglevel warn --check .
[1]

Or, you can use a glob-like pattern for brevity:

$ konk run c -n 'check:*'
[2]
[2] > check:lint
[2] > eslint .
[2]
[1]
[1] > check:format
[0]
[0] > check:build
[0] > tsc --noEmit
[0]
[1] > prettier --loglevel warn --check .
[1]

If you want to run commands concurrently but want to ensure output is not interleaved, use the -g/--aggregate-output flag:

$ konk run c -g -n 'check:*'
[0]
[0] > check:build
[0] > tsc --noEmit
[0]
[1]
[1] > check:format
[1] > prettier --loglevel warn --check .
[1]
[2]
[2] > check:lint
[2] > eslint .
[2]

You can also use the -L/--command-as-label flag to use the command itself as the process label:

$ konk run c -gL -n 'check:*'
[check:build ]
[check:build ] > check:build
[check:build ] > tsc --noEmit
[check:build ]
[check:format]
[check:format] > check:format
[check:format] > prettier --loglevel warn --check .
[check:format]
[check:lint  ]
[check:lint  ] > check:lint
[check:lint  ] > eslint .
[check:lint  ]

There is also a -c/--continue-on-error flag that will ensure other commands continue to run even if one fails. The default behavior is that all commands halt when any other command exits with a non-zero exit code.

$ konk run c -cgL -n 'check:*'
[check:build ]
[check:build ] > check:build
[check:build ] > tsc --noEmit
[check:build ]
[check:format]
[check:format] > check:format
[check:format] > prettier --loglevel warn --check .
[check:format]
[check:lint  ]
[check:lint  ] > check:lint
[check:lint  ] > eslint .
[check:lint  ]

Run Procfile: konk proc

Konk can also run a set of commands defined in a Procfile, using konk proc.

Given a Procfile like this:

foo: echo foo
bar: echo bar
$ konk proc
[foo] foo
[bar] bar

Konk will run the "foo" and "bar" commands concurrently (as if they were run with konk run c). In addition, Konk will pass any environment variables defined in a .env file to the running commands.