Source of Truth
The Scattered Truth
Here’s a typical project:
myapp/
├── main.go # the actual code
├── go.mod # Go dependencies
├── package.json # JS tooling deps
├── Dockerfile # how to containerize
├── docker-compose.yml # how to orchestrate
├── Makefile # how to build
├── .github/workflows/ # how to CI/CD
├── terraform/ # infrastructure
├── k8s/ # deployment manifests
└── README.md # "please read this first" Ten places where “truth” lives. Ten places that can drift out of sync.
Did you update the Dockerfile when you added that dependency? Did the README mention that new system library? Does the Makefile still work after you renamed that directory?
Every config file is a liability. Each one is a potential source of drift, confusion, and “works on my machine.”
The Koru Thesis
Your source code should be the single source of truth.
Not just for logic. For everything.
myapp/
└── main.kz # THE source of truth One file that contains:
- The code
- What system libraries it needs
- What packages it imports
- How to build it
- What containers it runs in
- (soon) How to deploy it
The compiler reads one file and knows everything.
The Evolution
We’ve been building toward this systematically.
Chapter 1: Import = Install
~import "$koru/sqlite3"
~koru.sqlite3:open(path: ":memory:")
| db d |> ... No package.json. The import IS the dependency declaration. Remove the import, the dependency vanishes from everywhere.
Chapter 2: The Compiler Runs Brew
~import "$std/deps"
~std.deps:requires.system {
"name": "sqlite3",
"check": "pkg-config --modversion sqlite3",
"brew": "sqlite3",
"apt": "libsqlite3-dev"
} System dependencies declared in source. Run koruc main.kz deps install and the compiler installs libsqlite3 for you.
Chapter 3: Build Configuration
~import "$std/build"
~std.build:requires {
exe.linkSystemLibrary("sqlite3");
exe.linkLibC();
} No separate build.zig to maintain. The source code tells the compiler how to link it.
Chapter 4: Infrastructure
This is new. And it’s wild.
~import "$koru/docker"
~koru.docker:image(tag: "myapp:latest") {
FROM alpine:3.18
COPY zig-out/bin/main /usr/local/bin/myapp
CMD ["myapp"]
} That’s a Dockerfile. Inside your source code.
Koru compiles to a native binary via Zig - no runtime needed. So your container is just Alpine + your binary. Tiny. Fast.
$ koruc main.kz # compile to native binary
$ koruc main.kz docker build # build the container
Building 1 Docker image(s)...
[1/1] Building myapp:latest...
✓ built myapp:latest No separate Dockerfile to maintain. The infrastructure IS the source code.
Multiple Services? Same File.
~import "$koru/docker"
// API server
~koru.docker:image(tag: "api:v1") {
FROM alpine:3.18
RUN apk add --no-cache sqlite-libs
COPY zig-out/bin/api /usr/local/bin/api
EXPOSE 8080
CMD ["api"]
}
// Background worker
~koru.docker:image(tag: "worker:v1") {
FROM alpine:3.18
COPY zig-out/bin/worker /usr/local/bin/worker
CMD ["worker"]
}
// CLI tool (for migrations, admin tasks)
~koru.docker:image(tag: "cli:v1") {
FROM alpine:3.18
RUN apk add --no-cache sqlite-libs
COPY zig-out/bin/cli /usr/local/bin/cli
ENTRYPOINT ["cli"]
} Three images. One source file. All native binaries on minimal Alpine containers.
$ koruc main.kz docker build
Building 3 Docker image(s)...
[1/3] Building api:v1...
✓ built api:v1
[2/3] Building worker:v1...
✓ built worker:v1
[3/3] Building cli:v1...
✓ built cli:v1 Each image is maybe 10-15MB. No Go runtime. No Node runtime. No Python interpreter. Just your code.
The Full Picture
Here’s what a complete Koru application looks like:
~import "$std/deps"
~import "$std/build"
~import "$koru/docker"
~import "$koru/sqlite3"
// System dependencies - the compiler runs brew/apt for you
~std.deps:requires.system {
"name": "sqlite3",
"check": "pkg-config --modversion sqlite3",
"brew": "sqlite3",
"apt": "libsqlite3-dev"
}
// Build configuration - how to link the binary
~std.build:requires {
exe.linkSystemLibrary("sqlite3");
}
// The infrastructure - containerization
~koru.docker:image(tag: "myapp:latest") {
FROM alpine:3.18
RUN apk add --no-cache sqlite-libs
COPY zig-out/bin/main /usr/local/bin/myapp
CMD ["myapp"]
}
// The actual code
~koru.sqlite3:open(path: "/data/app.db")
| db d |>
koru.sqlite3:exec(conn: d.conn, sql: "SELECT * FROM users")
| rows r |> process_users(r)
| err e |> log_error(e)
| err e |> fatal(e) Everything in one place:
- What system libraries to install (sqlite3 via brew/apt)
- How to build the binary (link libsqlite3)
- How to containerize it (Alpine + binary + sqlite-libs)
- What the application does (open db, query, process)
No drift. No “did you update X when you changed Y?” No archaeology across config files.
Why This Matters
Onboarding
Old way:
1. Read README
2. Install prerequisites (hope it's up to date)
3. Figure out build system
4. Debug why it doesn't work
5. Ask someone who knows Koru way:
git clone ...
koruc main.kz deps install
koruc main.kz docker build Done. The source code contains everything the compiler needs.
Refactoring
Old way: Change a dependency, then remember to update Dockerfile, docker-compose, CI config, README…
Koru way: Change the source. Everything else follows automatically.
Code Review
Old way: Review code changes, then separately review Dockerfile changes, then check if they’re consistent…
Koru way: One diff. All the truth in one place.
The Philosophy
Configuration files are a necessary evil that we’ve normalized. “Of course you need a Dockerfile separate from your code.” “Of course you need package.json.” “Of course you need terraform files.”
Why?
Your source code already describes what the application does. Why can’t it also describe what it needs, how to build it, and how to run it?
Source code as source of truth.
Not “source code plus a constellation of config files that hopefully agree with each other.”
Just source.
~import "$koru/docker"
~koru.docker:image(tag: "myapp:latest") {
FROM alpine:3.18
COPY zig-out/bin/main /usr/local/bin/myapp
CMD ["myapp"]
} That’s your Dockerfile. It lives with your code. It IS your code.
A native binary on a 5MB base image. No runtime. No interpreter. No dependency hell inside the container.
One file. One truth.