kindly 💖
A nice little task runner
[](https://hexdocs.pm/kindly/)
[](https://github.com/tynanbe/kindly/blob/main/LICENSE)
[](https://github.com/tynanbe/kindly/actions)
 •Â
[](https://hex.pm/packages/kindly)
[](https://npmjs.com/package/@tynanbe/kindly)
[](https://jsr.io/@tynanbe/kindly)
[](https://gleam.run/) [](https://www.typescriptlang.org/) [](https://ecma-international.org/publications-and-standards/standards/ecma-262/)  • [](https://nodejs.org/) [](https://deno.com/) [](https://bun.sh/)
[](https://github.com/tynanbe/kindly) ### [Quickstart](https://hexdocs.pm/kindly/quickstart.html)  • [API Reference](https://hexdocs.pm/kindly/kindly.html)  • [Examples](https://hexdocs.pm/kindly/examples.html) [• • •](https://youtu.be/aaj08tCfsVw)
Table of Contents
Features
- Simple CLI and API
- Shell completions
- Declarative and functional
- Works with Gleam, TypeScript, and JavaScript
- Runs with Node.js, Deno, or Bun
Example
Gleam
```gleam // dev/handbook.gleam import kindly.{type Handbook, task} pub fn main() -> Handbook { kindly.handbook(for: "example") |> task( doc: "Format source code", tags: ["format"], action: kindly.just(run: "gleam", with: ["format"]), ) |> task( doc: "Check source code formatting", tags: ["format-check", "check", "ci"], action: kindly.just(run: "gleam", with: ["format", "--check"]), ) } ```TypeScript & JavaScript
```typescript // handbook.ts, handbook.mjs, or handbook.js import kindly from "jsr:@tynanbe/kindly"; export default kindly.handbook({ for: "example" }) .task({ doc: "Format source code", tags: ["format"], action: kindly.just("deno", "fmt"), }) .task({ doc: "Check source code formatting", tags: ["format-check", "check", "ci"], action: kindly.just("deno", "fmt", "--check"), }); ```About
Kindly provides a simple yet flexible way to reference and run one or more user-defined tasks specific to your project.
By creating a project Handbook with minimal boilerplate, you can write your tasks in Gleam, TypeScript, or JavaScript for a better developer experience that can also make it easier to ensure your tasks will work in any environment with your runtime of choice (Node.js, Deno, or Bun).
Kindly bases task selection on a flat system of tags, although you could use it to emulate a command tree typical of other CLI tools. This allows you to group multiple tasks in a way that fits your project's needs and run all of them together or filter selected tasks for those in the group.
For example, suppose your Handbook has tasks with the following tags:
A. test, erlang
B. test, javascript
C. format-check, gleam
D. format-check, erlang
E. format-check, javascript
Invoking Kindly with different arguments would run various tasks as follows
(Note: You can always include the --help flag to show which tasks Kindly
plans to run given your other arguments):
kindly test erlang # A
kindly test # A, B
kindly javascript # B, E
kindly format-check --any gleam erlang # C, DThe first tag for each task should be the most specific way to reference that task. It's given special consideration in Kindly's help output.
When to consider Kindly
Kindly is for projects whose tasks are starting to outgrow a flat list of scripts.
Some handbooks use mostly direct task names. Others use grouped tasks, where one tag names the broader work and additional tags narrow it down. Kindly does not force one style. It is meant to support whichever shape fits the project and the way people actually use it.
It's an attractive option when tasks overlap, share helpers, or are easier to generate than hand-write. In those cases, composable task selection can be more useful than inventing a separate command name for every path through the task menu.
If your project only needs a few isolated commands, scripts may be simpler. If your tasks are related, grouped, or better expressed as code, Kindly may be a nice fit.
Try It
Gleam
```sh # Add kindly to your Gleam project’s dev dependencies gleam add --dev kindly # Print help info gleam run --module kindly # Run an example task gleam run -m kindly -- format-check ```Bun
```sh # Print help info bunx --bun @tynanbe/kindly # Run an example task bunx --bun @tynanbe/kindly format-check ```Deno
```sh # Print help info deno run --allow-all --reload jsr:@tynanbe/kindly # Run an example task deno run -Ar jsr:@tynanbe/kindly format-check ```Node.js
```sh # Print help info npx @tynanbe/kindly # Run an example task npx @tynanbe/kindly format-check ```Note: If your project uses a
handbook.gleamorhandbook.tsmodule and you want to run it with Node.js, it's recommended to run Node.js v24.0+, for type stripping support.
Installation
It's recommended to install Kindly globally with Deno, Bun, or your Node.js package manager of choice. This method is the simplest way to get shell completions, and Kindly will still run your handbook using your project's local Kindly dependency.
Bun
```sh bun install --global @tynanbe/kindly ```Deno
```sh deno install --global --allow-all jsr:@tynanbe/kindly ```Node.js
```sh # Or similar for pnpm, yarn, etc. npm install --global @tynanbe/kindly ```Run It
# Print help info
kindly
# Run an example task
kindly format-checkNote: If your project uses a
handbook.gleamorhandbook.tsmodule and you want to run it with Node.js, it's recommended to run Node.js v24.0+, for type stripping support.
Completions
After you've installed Kindly globally or worked out some other way to get
kindly on your $PATH, you can set up shell completions and Kindly will
suggest the tags for your project as well as its own flags.
Bash
 ```sh # ~/.bashrc if type kindly >/dev/null 2>&1; then eval "$(kindly --cue bash)" fi ```Fish
 ```sh # ~/.config/fish/config.fish if type kindly >/dev/null 2>&1 kindly --cue fish | source end ```PowerShell (pwsh)
 ```sh # ~/.config/powershell/profile.ps1 # or $HOME\Documents\PowerShell\profile.ps1 if (Get-Command -Name kindly -ErrorAction Ignore) { kindly --cue pwsh | Out-String | Invoke-Expression } # -Function MenuComplete is recommended, but # -Function Complete should also work Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete ```Zsh
 ```sh # ~/.zshrc if type kindly >/dev/null 2>&1; then eval "$(kindly --cue zsh)" fi ```Where Next?
Support
Contributions are welcome. Feel free to open an issue on GitHub to suggest a feature or report a bug.
If your project uses Kindly, you may wish to add a badge to your README.