jonnifyelixir
F5 · Pragmatic Programming / F5.03 · tracer-bullets

F5 · the engine · module 3

Tracer bullets: a walking skeleton

A running server and a domain model are still two separate things until one request travels the whole way between them. F5.03 fires a tracer bullet: it takes a single use case — enroll a learner — and drives it end to end through every layer at once, each layer present but minimal. A route on the thin server calls one function on the Learning context, which builds an %Enrollment{} and puts it in the store, and the handler answers. That thin vertical slice is the walking skeleton: real code, not a throwaway, and the frame every later feature drops into. Once it walks, the system grows by iterating the slice.

One use case cutting straight down the stack. Select a layer the slice passes through to see what it does — minimal, but real.

Once it walks, it grows by iterating

SLICES SHIPPED iteration → enroll a learnerslice 1 · the walking skeleton running end to end · 1 slice

[ slice 1 · enroll ]
One thin slice, alive end to end. Add the next and the frame holds.

A vertical slice

The skeleton cuts vertically, not horizontally. Instead of finishing the web layer, then the whole engine, then persistence — with nothing running until the end — it takes one path through all of them and makes only that path work. Every layer is touched, none is finished. Select a layer to see the one real thing the slice does there.

The enroll slice · select a layer

request ↓ ↑ response THIN WEB SERVER · F5.01 post "/enroll" CONTEXT API · F5.02 Learning.enroll(user_id, course_id) DOMAIN STRUCT · F5.02 %Enrollment{id: "ENR0Nb..."} THE STORE · F4 Store.put(enrollment)

layer: Context API

does: Learning.enroll/2

A walking skeleton is the whole system in miniature: thin everywhere, finished nowhere, but alive end to end. It turns “does this design hold together” into a question you answer on day one.

Three deep dives

In order: what a tracer bullet is and how it differs from a prototype; the walking skeleton that drives one use case through every layer; and how to iterate that slice into a real system.

F5.03.1
Tracer bullets vs prototypes
Both are built fast; one is real code you keep and build on, the other is throwaway code to answer a question.
F5.03.2
The walking skeleton
Enroll a learner end to end: post "/enroll" → Learning.enroll/2 → %Enrollment{} → store → 201.
F5.03.3
Iterating the slice
Grow the skeleton one thin vertical slice at a time — deliver a lesson, record progress — always running.

F5.01 + F5.02 · parts

A thin server that runs, and a domain model with a shape — but no request has crossed between them yet.

F5.03 · one slice through both

Drive enroll-a-learner end to end, thin at every layer, so the design is proven and the frame is set.

Start with tracer bullets vs prototypes, then the walking skeleton, then iterating the slice. The next module, F5.04 — Design by contract, hardens the commands the slice runs. For the runtime path through the engine, see the design brief: the command & event flow.

References

Building a system end to end first, as a thin slice that runs.

Sources

Related in this course