This document captures key learnings and decisions made during the development of krust with Claude.
## Project Overview
krust is a container image build tool for Rust applications, inspired by ko.build for Go. It builds static binaries and packages them into minimal OCI container images without requiring Docker.
## Key Design Decisions
### 1. Static Binaries with musl
We chose musl libc over glibc for static linking because:
- **True static linking**: glibc uses dynamic loading internally (NSS) which breaks in static binaries
- **Smaller binaries**: musl static binaries are 5-10x smaller than glibc
- **No runtime surprises**: glibc static binaries often fail with DNS resolution, user lookups, or locale issues
- **Container-optimized**: Perfect for minimal container images
### 2. Default Push Behavior
krust pushes images by default (use `--no-push` to skip) because:
- Aligns with the common workflow of building and immediately using images
- Enables the `docker run $(krust build)` pattern
- Reduces friction for the most common use case
### 3. Output Design
- **stdout**: Only the pushed image reference by digest (e.g., `ttl.sh/user/app@sha256:...`)
- **stderr**: All logging and progress information
- This enables composability with other tools
### 4. Image Naming Strategy
- Uses `KRUST_REPO` environment variable for repository prefix
- Automatically appends project name from Cargo.toml
- Can be overridden with `--image` flag
- Default tag is `latest`
## Technical Learnings
### OCI Image Building
1.**Layer Digest vs Diff ID**:
- Layer digest: SHA256 of the compressed (gzip) layer
- Diff ID: SHA256 of the uncompressed tar (goes in image config)