All Features
Scale Your Builds

Imports & Modules

Split your Jakefile across multiple files with namespaced imports. Essential for monorepos and team collaboration.

  • Namespaced imports@import "x.jake" as x
  • Scoped variables — Variables don't leak between files
  • Cross-file deps — Tasks can depend on imported tasks
Jakefile
# Jakefile
@import "jake/web.jake" as web
@import "jake/api.jake" as api
@import "jake/deploy.jake" as deploy

@default
task all: [web.build, api.build]
    echo "All packages built!"

task release: [all, deploy.production]
    echo "Released!"

Project Structure

Organize tasks by concern. Each team or domain gets their own file.

Recommended Structure
project/
├── Jakefile           # Main entry point
└── jake/
    ├── web.jake       # Web team owns this
    ├── api.jake       # API team owns this
    ├── mobile.jake    # Mobile team owns this
    └── deploy.jake    # DevOps owns this
Monorepo Structure
monorepo/
├── Jakefile
├── packages/
│   ├── web/
│   │   ├── src/
│   │   └── package.json
│   ├── api/
│   │   ├── src/
│   │   └── package.json
│   └── shared/
│       └── src/
└── jake/
    ├── web.jake
    ├── api.jake
    └── shared.jake

How It Works

Import files with a namespace, then reference tasks with the prefix.

jake/web.jake
# jake/web.jake
task build:
    npm --prefix packages/web build

task dev:
    npm --prefix packages/web dev

task test:
    npm --prefix packages/web test

Key Points

  • as web creates the namespace
  • Tasks become web.build, web.dev, etc.
  • Variables in web.jake don't affect the main Jakefile
Terminal
$ jake -l

Available tasks:
  all              Build all packages
  release          Release to production
  web.build        Build web package
  web.dev          Start web dev server
  web.test         Run web tests
  api.build        Build API package
  api.dev          Start API dev server
  deploy.staging   Deploy to staging
  deploy.production Deploy to production

$ jake web.build
 web.build
 web.build (2.4s)

Variable Scoping

Variables are scoped to their file. No accidental conflicts.

docker.jake
registry = "docker.io/mycompany"

task push:
    docker push {{registry}}}/app
Jakefile
registry = "gcr.io/my-project"  # Different!

@import "docker.jake" as docker

task push:
    echo {{registry}}}  # gcr.io/my-project
    # docker.push uses docker.io/mycompany

Use Cases

Patterns for organizing large projects.

Team Ownership

Each team maintains their own file. Merge conflicts are rare.

@import "jake/frontend.jake" as fe  # Frontend team
@import "jake/backend.jake" as be  # Backend team
@import "jake/infra.jake" as ops  # DevOps team

Environment Configs

Separate deployment logic per environment.

@import "jake/staging.jake" as staging
@import "jake/production.jake" as prod

task deploy-staging: [build, staging.deploy]
task deploy-prod: [build, prod.deploy]

Shared Utilities

Reusable utility tasks across projects.

# jake/utils.jake
task notify message:
    curl -X POST $SLACK_WEBHOOK -d '{"text":"{{message}}"}'

# Jakefile
@import "jake/utils.jake" as utils
@after deploy utils.notify "Deployed!"

Cross-File Dependencies

Modules can depend on each other.

# jake/web.jake
@import "shared.jake" as shared

task build: [shared.build]  # Depends on shared
    npm run build

vs Make

Make's include is global and fragile. Jake's imports are namespaced.

Makefile
# Global include - variables and
# targets can conflict!
include scripts/docker.mk
include scripts/k8s.mk

# Which "build" is this?
Jakefile
@import "scripts/docker.jake" as docker
@import "scripts/k8s.jake" as k8s

# Clear: docker.build vs k8s.build

Try Imports

Organize your builds at any scale.