Single Go binary · Linux · macOS · Windows

Your project's tasks, one line at a time.

One binary. Plain-text .wf files. No YAML. WF runs your build, install and deploy steps from top to bottom, and shows you exactly what ran.

How it works

Write. Run. Read.

Three steps, nothing hidden. Every line of a .wf file is one command, run in the order you wrote it.

1. Write

Group your commands in named sections of a .wf file: [deploy] # Deploy the app, then one command per line.

2. Run

wf deploy reads every .wf file in the current folder and runs the deploy section. wf build inside it calls another section.

3. Read

Each command is printed, its output framed, its duration shown. Sub-workflows are indented like a tree. The first failure stops everything.

Example

The same deploy, four ways.

Check that the tools are installed, install the dependencies, clear the cache, write a secret, start the containers. Read the WF version once and you know what it does.

deploy.wf · WF · 7 lines

[deploy] # Deploy the application
require docker composer
run composer install --no-dev
remove var/cache
write .env.local APP_SECRET=${GENERATE_SECRET}
docker_compose up -d
notify_success "Deployed!"

Makefile · Make · 10 lines

# Deploy the application
.PHONY: deploy
deploy:
	@command -v docker >/dev/null || (echo "docker is required" && exit 1)
	@command -v composer >/dev/null || (echo "composer is required" && exit 1)
	composer install --no-dev
	rm -rf var/cache
	echo "APP_SECRET=$$(openssl rand -hex 32)" >> .env.local
	docker compose up -d
	@echo "Deployed!"

To know: tabs only, $$ escaping, .PHONY, shell commands, openssl installed.

justfile · just · 9 lines

# Deploy the application
deploy:
    @command -v docker >/dev/null || (echo "docker is required" && exit 1)
    @command -v composer >/dev/null || (echo "composer is required" && exit 1)
    composer install --no-dev
    rm -rf var/cache
    echo "APP_SECRET=$(openssl rand -hex 32)" >> .env.local
    docker compose up -d
    @echo "Deployed!"

To know: recipe syntax, shell commands, openssl installed.

Taskfile.yml · Task · 16 lines

version: '3'

tasks:
  deploy:
    desc: Deploy the application
    preconditions:
      - sh: command -v docker
        msg: docker is required
      - sh: command -v composer
        msg: composer is required
    cmds:
      - composer install --no-dev
      - rm -rf var/cache
      - echo "APP_SECRET=$(openssl rand -hex 32)" >> .env.local
      - docker compose up -d
      - echo "Deployed!"

To know: YAML indentation, Task keys, shell commands, openssl installed.

Why WF

Made for the steps you repeat.

Installing, building, deploying: a list of commands in a fixed order. You need them written down and run the same way every time, not a programming language.

Nothing to learn

A section is [name], a command is one line, a comment starts with #. Anyone on your team can read a .wf file.

No shell in between

run composer install runs composer with install. Quotes work like in a terminal; pipes and globs stay plain text. No surprises.

Native file commands

mkdir, write, copy, move, remove and set_permissions are built into WF. They do not depend on the tools of the machine.

Output you can read

A tree of workflows and commands, a timer on each one, and a clear message on the line that failed.

Compare

Like Make or just, without the syntax.

Those tools can do anything, so they need a language. WF only runs commands in order, so it needs none.

Shell scriptMakejustTaskWF
InstallBash or PowerShellmakeSingle binarySingle binarySingle Go binary
File.sh / .ps1MakefilejustfileTaskfile.yml.wf files
SyntaxA programming languageTargets, tabs, make functionsRecipes, parameters, expressionsYAML, Go templatesOne command per line
Conditions & loopsYesYesYesYesNo, by design
OutputRawRawRawRaw or prefixedTree with a timer per command

Scope

What WF will never do

A single Go file you can read in one sitting stays a tool you can trust. WF will not grow into another scripting language.

  • add conditions
  • add loops
  • add functions
  • run steps in parallel
  • hide a shell behind your commands
  • load plugins
  • require a YAML file

Get WF

One download. Five platforms.

Linux x64 and ARM64, macOS Intel and Apple Silicon, Windows x64. Download the binary, put it in your PATH, and you are ready.