Skip to content

Migrating from Taskfile

Taskfile (taskfile.dev) is a popular YAML-based task runner. Jake provides similar features with a more concise syntax.

TaskfileJake
version: '3'Not needed
tasks: blockTop-level recipes
desc:@desc or doc comment
cmds: arrayIndented commands
deps:[dependencies]
vars:Variable assignments
dotenv:@dotenv
sources:/generates:File recipe
includes:@import
preconditions:@needs, @require
prompt:@confirm
version: "3"
tasks:
build:
desc: Build the application
cmds:
- go build -o app
- echo "Done"
# Build the application
task build:
go build -o app
echo "Done"
version: "3"
vars:
APP_NAME: myapp
VERSION:
sh: git describe --tags
tasks:
show:
cmds:
- echo "{{.APP_NAME}} v{{.VERSION}}"
app_name = "myapp"
version = `git describe --tags`
task show:
echo "{{app_name}} v{{version}}"
tasks:
build:
deps: [clean, install]
cmds:
- go build -o app
clean:
cmds:
- rm -rf dist/
install:
cmds:
- go mod download
task build: [clean, install]
go build -o app
task clean:
rm -rf dist/
task install:
go mod download
tasks:
bundle:
desc: Bundle JavaScript files
sources:
- src/**/*.js
- package.json
generates:
- dist/bundle.js
cmds:
- esbuild src/index.js --bundle --outfile=dist/bundle.js
# Bundle JavaScript files
file dist/bundle.js: src/**/*.js package.json
esbuild src/index.js --bundle --outfile=dist/bundle.js

Jake uses checksum-based tracking like Taskfile, but with a cleaner syntax.

version: "3"
dotenv: [".env", ".env.local"]
env:
DEBUG: true
tasks:
serve:
env:
PORT: 8080
cmds:
- ./server
@dotenv
@dotenv ".env.local"
@export DEBUG=true
task serve:
PORT=8080 ./server
version: "3"
includes:
docker:
taskfile: ./tasks/Docker.yml
dir: ./docker
vars:
IMAGE: myapp
tasks:
build:
cmds:
- task: docker:build
@import "tasks/docker.jake" as docker
task build: [docker.build]
echo "Build complete"
tasks:
deploy:
preconditions:
- sh: test -f .env
msg: ".env file required"
- sh: command -v kubectl
msg: "kubectl not installed"
cmds:
- kubectl apply -f deploy.yaml
@needs kubectl
task deploy:
@if not exists(.env)
echo ".env file required"
exit 1
@end
kubectl apply -f deploy.yaml

Or more concisely with @require for environment checks:

@require KUBECONFIG
@needs kubectl
task deploy:
kubectl apply -f deploy.yaml
tasks:
deploy:
prompt: Deploy to production?
cmds:
- ./deploy.sh
task deploy:
@confirm "Deploy to production?"
./deploy.sh
tasks:
build-images:
vars:
IMAGES: nginx postgres redis
cmds:
- for: { var: IMAGES, split: " " }
cmd: docker build -t {{.ITEM}} .
task build-images:
@each nginx postgres redis
docker build -t {{item}} .
@end
tasks:
test:
cmds:
- docker-compose up -d
- defer: docker-compose down
- go test ./...
task test:
@pre docker-compose up -d
go test ./...
@post docker-compose down

Post-hooks run even if the recipe fails.

tasks:
install:
platforms: [linux, darwin]
cmds:
- make install
install-windows:
platforms: [windows]
cmds:
- choco install myapp
@platform linux macos
task install:
make install
@platform windows
task install:
choco install myapp
version: "3"
dotenv: [".env"]
vars:
APP_NAME: myapp
BUILD_DIR: dist
tasks:
default:
deps: [build]
build:
desc: Build the application
deps: [clean, install]
sources:
- src/**/*.go
- go.mod
generates:
- "{{.BUILD_DIR}}/{{.APP_NAME}}"
cmds:
- mkdir -p {{.BUILD_DIR}}
- go build -o {{.BUILD_DIR}}/{{.APP_NAME}}
install:
desc: Install dependencies
cmds:
- go mod download
sources:
- go.mod
- go.sum
clean:
desc: Remove build artifacts
cmds:
- rm -rf {{.BUILD_DIR}}
test:
desc: Run tests
deps: [build]
cmds:
- go test ./... -v
deploy:
desc: Deploy to server
deps: [test]
prompt: "Deploy to production?"
cmds:
- rsync -avz {{.BUILD_DIR}}/ server:/app/
@dotenv
app_name = "myapp"
build_dir = "dist"
@default
task build: [clean, install, dist/{{app_name}}]
@desc "Build the application"
file dist/{{app_name}}: src/**/*.go go.mod
mkdir -p {{build_dir}}
go build -o {{build_dir}}/{{app_name}}
task install:
@desc "Install dependencies"
@cache go.mod go.sum
go mod download
task clean:
@desc "Remove build artifacts"
rm -rf {{build_dir}}
task test: [build]
@desc "Run tests"
go test ./... -v
task deploy: [test]
@desc "Deploy to server"
@confirm "Deploy to production?"
rsync -avz {{build_dir}}/ server:/app/
TaskfileJake
taskjake
task buildjake build
task --listjake --list
task --dryjake -n
task --watchjake -w
task --parallel t1 t2jake -j t1 t2
task --forceDelete cache, re-run
task VAR=valuejake var=value
  1. Syntax: Jake uses a Makefile-inspired DSL instead of YAML
  2. File recipes: Jake has dedicated file keyword vs sources/generates
  3. Simpler structure: No version declaration or nesting required
  4. Single binary: Both are single binaries, but Jake is smaller (Zig vs Go)
  • Checksum-based file tracking
  • Parallel execution
  • Includes with namespacing
  • Environment variable support
  • Watch mode
  • Cross-platform support