# Build Tools

Compilation, bundling, task automation, and build systems for modern development.

---

## Build Tool Categories

| Category | Purpose | Examples |
|---|---|---|
| **Language-native** | Compile, test, package for specific language | `cargo`, `go build`, `gradle`, `mvn` |
| **Polyglot/Task runners** | Orchestrate multi-language builds | `make`, `just`, `task`, `earthly` |
| **JS/TS Bundlers** | Bundle, optimize, transform frontend code | Vite, esbuild, Turbopack, Rspack |
| **Container/Cloud** | Build images, deploy | Docker, Buildpacks, Kaniko, BuildKit |
| **Monorepo** | Manage multiple packages in one repo | Turborepo, Nx, Bazel, Moonrepo |

---

## Language-Native Build Tools

### Rust: Cargo
```toml
# Cargo.toml
[package]
name = "my-service"
version = "0.1.0"
edition = "2021"

[workspace]
members = ["domain", "application", "infrastructure", "api"]

[profile.release]
lto = true
codegen-units = 1
strip = true
panic = "abort"

[features]
default = ["postgres"]
postgres = ["sqlx/postgres"]
sqlite = ["sqlx/sqlite"]
```

**Commands**: `cargo build`, `cargo test`, `cargo check`, `cargo clippy`, `cargo fmt`, `cargo audit`

### Go: Go Build
```bash
# Build
go build -o bin/api ./cmd/api

# Build with version info
go build -ldflags="-X main.version=1.2.3 -X main.commit=$(git rev-parse HEAD)" -o bin/api ./cmd/api

# Cross-compile
GOOS=linux GOARCH=amd64 go build -o bin/api-linux ./cmd/api
```

**Commands**: `go build`, `go test`, `go vet`, `go fmt`, `go mod tidy`, `go generate`

### JVM: Gradle (Kotlin DSL) — Recommended
```kotlin
// build.gradle.kts
plugins {
    id("org.springframework.boot") version "3.2.0"
    id("io.spring.dependency-management") version "1.1.4"
    kotlin("jvm") version "1.9.0"
    kotlin("plugin.spring") version "1.9.0"
    kotlin("plugin.serialization") version "1.9.0"
    id("com.github.johnrengelman.shadow") version "8.1.1" // Fat JAR
}

group = "com.example"
version = "1.0.0"

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(21))
    }
}

dependencies {
    implementation(platform("org.springframework.boot:spring-boot-dependencies:3.2.0"))
    implementation("org.springframework.boot:spring-boot-starter-webflux")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("io.kotest:kotest-runner-junit5:5.8.0")
}

tasks.withType<Test> {
    useJUnitPlatform()
    testLogging { events("passed", "skipped", "failed", "standardOut", "standardError") }
}

tasks.withType<ShadowJar> {
    archiveClassifier.set("")
    manifest {
        attributes["Main-Class"] = "com.example.ApplicationKt"
    }
}
```

**Commands**: `./gradlew build`, `./gradlew test`, `./gradlew bootRun`, `./gradlew shadowJar`

### Python: uv / Hatch
```toml
# pyproject.toml (uv/hatch)
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-service"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
    "fastapi>=0.109",
    "pydantic>=2.6",
    "sqlalchemy>=2.0",
]

[project.optional-dependencies]
dev = ["pytest>=8.0", "ruff>=0.3", "mypy>=1.8"]

[tool.hatch.envs.dev]
dependencies = ["dev"]

[tool.hatch.scripts]
dev = "uvicorn main:app --reload"
test = "pytest"
lint = "ruff check . && mypy src"
format = "ruff format ."
```

**Commands**: `uv sync`, `uv run pytest`, `uv run ruff check`, `hatch run test`

---

## JavaScript/TypeScript Bundlers

| Tool | Best For | Key Features |
|---|---|---|
| **Vite** | Apps (React, Vue, Svelte, Solid) | Dev server, HMR, optimized prod build |
| **esbuild** | Libraries, ultra-fast builds | Go-based, 10-100x faster |
| **Turbopack** | Next.js 14+, Turborepo | Rust-based, incremental |
| **Rspack** | Webpack-compatible, fast | Rust-based, webpack API |
| **Rollup** | Libraries, ESM | Tree-shaking, flexible plugins |
| **tsup** | TS libraries | esbuild-based, d.ts generation |

### Vite Config (Modern Default)
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig({
  plugins: [react(), tsconfigPaths()],
  build: {
    target: 'es2022',
    minify: 'esbuild',
    cssCodeSplit: true,
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom', 'react-router-dom'],
        },
      },
    },
  },
  server: {
    port: 3000,
    proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } },
  },
});
```

### Library Build (tsup)
```json
// package.json
{
  "scripts": {
    "build": "tsup src/index.ts --format esm,cjs --dts --external react",
    "dev": "tsup src/index.ts --format esm,cjs --dts --watch"
  },
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.js",
      "types": "./dist/index.d.ts"
    }
  }
}
```

---

## Task Runners / Polyglot Orchestration

### Just (Modern Make)
```bash
# justfile
set shell := ["bash", "-cu"]

default: help

help:
    @just --list

build: build-rust build-go build-frontend

build-rust:
    cargo build --release --workspace

build-go:
    CGO_ENABLED=0 go build -o bin/api ./cmd/api

build-frontend:
    cd frontend && pnpm build

test: test-rust test-go test-frontend

test-rust:
    cargo test --workspace

test-go:
    go test ./...

test-frontend:
    cd frontend && pnpm test

lint: lint-rust lint-go lint-frontend

lint-rust:
    cargo clippy --workspace -- -D warnings
    cargo fmt --check --workspace

lint-go:
    golangci-lint run ./...

lint-frontend:
    cd frontend && pnpm lint

dev:
    just build && docker compose up -d

clean:
    cargo clean
    go clean
    rm -rf bin/ frontend/dist/
```

### Task (Go-based, YAML)
```yaml
# Taskfile.yml
version: '3'
vars:
  GREETING: "Hello, {{.USER}}!"

tasks:
  default:
    cmds:
      - task --list
    silent: true

  build:
    deps: [build-rust, build-go, build-frontend]

  build-rust:
    cmd: cargo build --release --workspace

  build-go:
    cmd: CGO_ENABLED=0 go build -o bin/api ./cmd/api

  build-frontend:
    dir: frontend
    cmd: pnpm build

  test:
    deps: [test-rust, test-go, test-frontend]

  lint:
    deps: [lint-rust, lint-go, lint-frontend]
```

### Earthly (Containerized, Reproducible)
```dockerfile
# Earthfile
VERSION 0.8
FROM rust:1.78 AS rust-build
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release

FROM golang:1.22 AS go-build
WORKDIR /app
COPY go.mod go.sum ./
COPY cmd ./cmd
COPY internal ./internal
RUN CGO_ENABLED=0 go build -o /build/api ./cmd/api

FROM node:20 AS frontend-build
WORKDIR /app
COPY frontend/package.json frontend/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY frontend/ ./
RUN pnpm build

build:
    BUILD +rust-build+go-build+frontend-build
SAVE ARTIFACT /app/target/release/my-service AS LOCAL rust-binary
SAVE ARTIFACT /build/api AS LOCAL go-binary
SAVE ARTIFACT /app/dist AS LOCAL frontend-dist
```

---

## Monorepo Tools

| Tool | Language | Best For |
|---|---|---|
| **Turborepo** | JS/TS/Go/Rust | Remote caching, task pipeline |
| **Nx** | JS/TS/Java/Go | Affected computation, generators |
| **Bazel** | Polyglot | Hermetic, remote execution |
| **Moonrepo** | Rust/JS/Go | Rust-first, fast |
| **Pants** | Python/Go/Java/Scala | Fine-grained, remote caching |

### Turborepo (Most Popular for JS/TS)
```json
// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", "build/**", "target/release/**"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    },
    "lint": {
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  },
  "globalEnv": ["DATABASE_URL", "REDIS_URL"]
}
```

```json
// package.json (workspace root)
{
  "private": true,
  "workspaces": [
    "packages/*",
    "services/*",
    "tools/*"
  ],
  "scripts": {
    "build": "turbo run build",
    "test": "turbo run test",
    "lint": "turbo run lint",
    "dev": "turbo run dev",
    "format": "prettier --write \"**/*.{ts,tsx,json,md}\""
  },
  "devDependencies": {
    "turbo": "latest",
    "prettier": "latest"
  }
}
```

---

## Container Build

### Dockerfile (Multi-stage, Optimized)
```dockerfile
# Build stage
FROM rust:1.78 AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y pkg-config libssl-dev
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release

# Runtime stage
FROM gcr.io/distroless/cc-debian12
COPY --from=builder /app/target/release/my-service /my-service
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/my-service"]
```

### BuildKit Features (Docker 23+)
```dockerfile
# syntax = docker/dockerfile:1.7
# Cache mounts for dependencies
RUN --mount=type=cache,target=/root/.cargo/registry \
    --mount=type=cache,target=/app/target \
    cargo build --release

# Secret mounts (build-time only)
RUN --mount=type=secret,id=npm_token \
    npm ci --registry=https://npm.pkg.github.com
```

### Buildx (Multi-platform)
```bash
docker buildx create --use --name mybuilder
docker buildx build --platform linux/amd64,linux/arm64 -t myorg/my-service:1.0.0 --push .
```

---

## CI/CD Integration

### GitHub Actions (Reusable Workflows)
```yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  build:
    uses: ./.github/workflows/reusable-build.yml
    secrets: inherit

  test:
    needs: build
    uses: ./.github/workflows/reusable-test.yml
    secrets: inherit

  lint:
    uses: ./.github/workflows/reusable-lint.yml
```

### Caching Strategy
```yaml
- name: Cache Rust
  uses: Swatinem/rust-cache@v2
  with:
    key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: Cache Go
  uses: actions/cache@v4
  with:
    path: |
      ~/go/pkg/mod
      ~/.cache/go-build
    key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}

- name: Cache Node
  uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      ~/.cache/pnpm
    key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }}

- name: Cache Gradle
  uses: actions/cache@v4
  with:
    path: |
      ~/.gradle/caches
      ~/.gradle/wrapper
    key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
```

---

## Build Performance Tips

| Technique | Impact |
|---|---|
| **Incremental builds** | Only rebuild changed modules (Turborepo, Nx, Bazel) |
| **Remote caching** | Share cache across CI/local (Turbo, Nx, Bazel, Gradle Enterprise) |
| **Parallel execution** | `cargo test --jobs 4`, `go test -p 4`, `gradle --parallel` |
| **Dependency caching** | Cache `~/.cargo`, `~/go/pkg/mod`, `~/.npm`, `~/.gradle` |
| **Shallow clones** | `git clone --depth=1` in CI (if history not needed) |
| **Layer caching** | Order Dockerfile: deps → build → copy source |
| **BuildKit** | Parallel stages, cache mounts, secret mounts |

---

## Related Notes

- [[Tools/Developer-Tools]] — IDE, debugging, profiling
- [[Tools/Static-Analysis]] — Linting, type checking
- [[Tools/Package-Management]] — Dependencies, registries
- [[Languages/*]] — Language-specific build tools
- [[DevOps/CI-CD-Best-Practices]] — Pipeline integration
- [[DevOps/Infrastructure-as-Code]] — Terraform, Pulumi builds

---

*Sources: Cargo, Go, Gradle, Vite, esbuild, Turborepo, Nx, Bazel, Earthly, Docker BuildKit, GitHub Actions, CNCF CI/CD Landscape*