Maslow's Hierarchy of Developer Needs
Maslow's hierarchy of needs is the Psych 101 version of how people's needs change as their circumstances do. A person on fire doesn't need more close friends, they need a bucket of water.
Similarly, not all development projects have the same needs at the same time.
In practice these needs stack, and you cannot skip the lower ones.
- Builds That Work
- Local Execution & Fast Feedback
- Tests That Tell the Truth
- Humane Feedback
- Smooth Changes
Builds That Work
If you walk into a dev shop with a reasonable laptop, you should be able to build the software without too much fanfare. Maybe there are build dependencies that can't be avoided and are difficult to install as part of a build.sh script. If a bit of the README has to be followed, that is fine -- as long as it is clear and minimal.
If the build requires someone to remember to copy a file, click a checkbox, or incant a ritual, that step has already escaped the system. Any step that isn't automated is a potential source of mistakes, and those mistakes will always happen. They'll happen at more stressful times, which is exactly the wrong time.
At the end of this, you should have a single, simple command that builds the whole thing at once. Maybe it takes a long time. That's fine. IDEs aren't a solution here. They're great tools for developers, but they are not an authority on whether the system works. They can be an extremely useful view of the system, but they aren't authoritative when it comes to reality.
The reality is what happens when the code is checked out on a clean machine and built. My editor is a useful view of the system. The system itself doesn't know or care what my editor thinks.
Local Execution & Fast Feedback
How much work do you have to do to change something and see the result? Do you have to juggle Docker containers? Are there cloud resources in play? Phone emulators? Modern systems are complicated and are rarely monoliths.
It doesn't matter. The harder your software is to run, the more important it is that you can run it with one command. That command can be 500 lines of cursed bash script. It just has to exist. Once it exists, it can be source controlled, shared, reasoned about, and composed with.
Tests That Tell the Truth
You've written your code, you've run your code, you like your code. Did you break anything?
If you run the tests and they come back green, are you sure everything is fine? If they come back red, are you sure you're at fault? This matters. If tests aren't trustworthy, that doubt infuses everything you do from then on. "The tests are flaky" lowers the value of the whole suite. It also lowers the motivation to add to it.
If a test doesn't work, it eventually needs to be fixed or disabled until it can be.
Humane Feedback
Compilers get a bad rap because most people meet them when they're still learning. At that stage, they mostly just tell you that you're wrong for reasons you don't quite understand. It's easy to internalize that as hostility. And that vibe can follow along even once you're an expert. The compiler is annoying and pedantic and who cares.
But the compiler isn't a critic. It's not trying to teach anything. It's just being very literal about the rules. And that's good. That's the nicest thing a piece of software can do for a person. Being told you're wrong here is a gift. It's cheap, it's specific, and it happens before it hurts.
The compiler is the best representation of a computer's understanding of the code. The computer is going to do exactly what it's told, so it's in everyone's interest to make that crystal clear. If the compiler is nervous about something, that's a strong signal. Often, yes, the compiler is being a bit of a worrier. But it doesn't cost you anything to fix. Make it clear to the compiler what you mean, and be willing to change things a bit for its benefit.
In practice, keeping warnings and lints at exactly zero turns out to be a good way to keep a workspace usable.
Smooth Changes
When everything is in place -- the build is easy, the tests are solid, and the linter is watching -- development changes.
You can change the signature of that core function.
The compiler and linter may light up. That's not a list of moral judgments. That's your checklist. Once you fix those, you're done. The tests can be a victory lap, not an ordeal.
Big refactors may mean a longer checklist, but the idea remains: when it's done, you're done.
You can even take risks chasing performance. You can plug in a complex algorithm or experiment with SIMD intrinsics without fear. The system has your back. It will tell you, immediately and specifically, where there's work left to be done.