In today’s tooltip I’ll be showcasing go-task. It’s a tool designed to make executing terminal commands or even lists of commands needed for specific operations easier.

The example used is GNU make, but there are plenty of other great use cases. In this article, I’ll cover why you should be using it and how to use it.


If you’ve ever gotten annoyed at long readme installation or execution instructions, you know the pain of having to execute a long list of commands to get a dev environment up an running. It can be a massive pain, especially if there are a number of complicated instructions.

Go-task solves this problem by combining terminal commands with a light sprinkling of application features that allow you to create scripts and small applications that don’t require much command-line knowledge to execute.

Installing go-task is very simple. I used to brew install go-task to install it on my local machine, but there are many ways to install it. Check the installation instructions for more info.


The basic task file consists of a task name and command to be executed, written in YAML format.

# Taskfile.yml
version: '3'

tasks:
  greet:
    cmds:
      - echo "Hello World"

To execute the command, you simply run task greet from the same directory as the Taskfile.yml file.


A good real-world example is running tests. I sometimes like running my NodeJS tests with a local mongo database available because it lets me test for errors coming from mongo schema. This isn’t going to be an article about best practices for testing, but for obvious reasons, testing using 3rd party applications is not ideal.

Mocking responses from the database will generally be more reliable, but writing these tests is also more time-consuming. Time is the one resource I rarely have in abundance when working for clients, so I sometimes choose the path of least resistance.

I run my tests with a local MongoDB docker instance, but I want to ensure my environment is clean before running my tests. This command looks something like this:

version: '3'

env:
  DB_SERVICE_NAME: mongo

tasks:
  test:
    cmds: 
      - "
      read -p 'This will reset your local environment. Are you sure? (Y/n) ' -r;
      if [[ ! $REPLY =~ ^[Yy]$ ]]
      then
          exit 1;
      fi
      "
      - docker-compose stop -t 0 $DB_SERVICE_NAME
      - docker-compose rm -f $DB_SERVICE_NAME
      - rm -rf node_modules
      - rm -rf docker/db
      - docker-compose up -d $DB_SERVICE_NAME
      - npm install
      - npm run test

As you can see, I’m asking the user to confirm before moving ahead, and then I run a series of commands:

  • Stop the mongo container if it’s running.
  • Remove the mongo container entirely.
  • Remove all install node modules.
  • Remove the local folder I store my database data in.
  • Bring up a new mongo database.
  • Install all node modules from the package-lock.json file.
  • Run my test command as defined in my package.json

This is done by simply calling task test on any local environment.


Global environment variables can and should be used in Taskfile.yml, but it’s important to note that they can be used for both specific commands and globally for the script.

version: '3'

env:
  DB_SERVICE_NAME: mongo

dotenv: ['.env', 'config.env', ...]

tasks:
  env:
    LOCAL_ENV: "example-env"
  dotenv: ['example.env']
  cmds:
    - echo "Local env: $LOCAL_ENV"

The dotenv format can also be used, and multiple files can be imported if needed. Remember that these environment variables are also available for any scripts or code you run from your task. So in the test example, the variables I defined are available during the test runs. I can use this to control the application’s aspects during the tests if my application supports it.


The use cases of go-task is endless. You can run tests to compile CSS or javascript, download test data, or even build entire development setups with a single command.

The best part is that I no longer have to keep a bin or script directory in all my projects. My readme documentation now includes a few short commands and descriptions of what they do, rather than line upon line of commands someone needs to enter manually.

Is it better than having specific scripts? From a technical standpoint, it’s the same because I’ve simply moved my scripts into a yaml format. But for handing projects over to new developers or running commands during releases, go-task makes my life a lot easier.

Have you used go-task? What are some use cases you’d like to try? Let me know in the comments.


Get go-task at https://taskfile.dev/, and don’t forget to follow me on Medium or LinkedIn to see what else I get up to.