Skeleton Code and the Lie of the Clean Start
I have a project with five commits that are all some variation of "added skeleton." At what point does scaffolding become procrastination?
Here's the actual history, more or less:
- Added shell for commands
- Added skeleton code to take daemon and ctl commands
- Added skeleton run_daemon and allowed running from main
- Added a headless UI and started to do config and setup in run_daemon
Four commits. No real functionality. A lot of structure. The project looks, from the outside, like something is happening. There are files. There are function signatures. There are placeholder comments where the hard bits will eventually go. The scaffolding is tidy.
The hard bits are not in there.
I've noticed I do this on projects where I don't quite know what I am doing. Not the easy problems, where you just sit down and write the thing. The ones where there's a decision that I keep avoiding. Should the daemon handle config itself or accept it from the controller? How does the headless UI actually talk to the running process? What's the right shape for the commands?
These are real questions I need to answer. And I avoid answering them by building a very nice skeleton to put the answers in once I've figured them out.
The skeleton feels like progress. It has commits. It compiles. It looks like a codebase. But it's not really code yet — it's a drawing of a house. You can walk around it and point at where the kitchen will go, but you can't make tea.
The thing is that skeleton code is useful. Getting the shape of a solution down before the details can help. I'm not against scaffolding. Sometimes you need to rough out the structure before you can see what's missing.
But there's a version of it that isn't really about the structure. It's about having something to do that isn't the scary bit. Adding a shell for commands is easy. Deciding what those commands actually need to do — and then making that work — is where you get stuck. Might have to admit you don't know something. Might write something that doesn't work.
The skeleton lets you keep moving without confronting any of that.
I think the important thing is what happens after the skeleton. If the next thing is real implementation, code that actually does something — then the scaffolding was doing its job. If the next thing is more skeleton, more structure, more "just getting the shape right," then something else is going on.
In my project, the commits after the skeletons are still pretty thin. Which means I was probably not scaffolding toward a solution. I was scaffolding to feel like I was moving.
I don't have a clean fix for this. I notice it more now. When I find myself reaching for another skeleton, I've started asking what question I'm actually avoiding. Usually there's something specific — a bit of design I haven't committed to, a part of the problem I don't understand. The skeleton is a symptom.
The real work is sitting with the uncomfortable questions long enough to actually answer them. Which is less satisfying than a tidy directory structure, but does eventually result in software that does something.
The shell for commands is still there. It's still empty. One day I'll have to decide what goes in it.
