All Features
The Make Advantage

File Targets

Track file modifications and only rebuild when sources change. Chain builds together for multi-stage pipelines that skip unnecessary work automatically.

  • Glob patterns — Match files with src/**/*.ts
  • Dependency chains — File targets can depend on other file targets
  • Automatic skip — "Up to date" when nothing changed
Jakefile
# File target with glob pattern
file dist/bundle.js: src/**/*.ts
    esbuild src/index.ts --bundle --outfile=dist/bundle.js

# Chain file targets together
file dist/app.min.js: dist/bundle.js
    terser dist/bundle.js -o dist/app.min.js

# Task depends on file target
task build: [dist/app.min.js]
    echo "Build complete!"

How It Works

Jake checks modification times and only runs commands when sources are newer than outputs.

1. First Run

Jake checks if dist/bundle.js exists. It doesn't, so Jake runs the build command.

2. Second Run

Jake expands src/**/*.ts and compares timestamps. All sources are older than the output, so Jake skips the build.

3. After Edit

You edit src/index.ts. Now one source is newer than the output, so Jake rebuilds.

Terminal
$ jake build
 dist/bundle.js
  esbuild src/index.ts --bundle --outfile=dist/bundle.js
 dist/bundle.js (0.42s)
 dist/app.min.js
  terser dist/bundle.js -o dist/app.min.js
 dist/app.min.js (0.18s)
 build
  echo "Build complete!"
 build (0.01s)

$ jake build  # Run again
 dist/bundle.js (up to date)
 dist/app.min.js (up to date)
 build (0.01s)

Glob Patterns

Match files with powerful glob syntax—no need to list every file manually.

Pattern Matches
*.ts TypeScript files in current directory
**/*.ts TypeScript files anywhere (recursive)
src/**/*.{ts,tsx} TS/TSX files under src/
[abc].txt a.txt, b.txt, or c.txt
??.js Two-character JS files

Use Cases

File targets work with any build tool or language.

TypeScript Builds

file dist/index.js: src/**/*.ts tsconfig.json
    npx tsc

CSS Processing

file dist/styles.css: src/**/*.scss
    sass src/main.scss dist/styles.css

Binary Compilation

file app: *.c *.h
    gcc -o app *.c

Docker Images

file .docker-built: Dockerfile src/**/*
    docker build -t myapp . && touch .docker-built

vs Make

Same power, cleaner syntax.

Makefile Make
# Makefile
dist/app.js: $(wildcard src/*.ts)
	esbuild src/index.ts --bundle -o $@
Jakefile Jake
# Jakefile
file dist/app.js: src/**/*.ts
    esbuild src/index.ts --bundle --outfile=dist/app.js
Native globs
No $(wildcard ...) needed
No magic vars
No $@, $<, $^ to memorize
Flexible indent
Tabs or spaces work

Try File Targets

Add incremental builds to your project in minutes.