Hard-won Software Development Habits
This post is about how to write software well. It was inspired by this post with a similar title. Read it (and write yours?)!
These ideas aren't advice but rather notes about how I do my best work. If you're new, some of these ideas might seem obvious, but they get harder as you progress, or your understanding of them deepens, or you'll encounter engineers who embody them in surprising ways.
Be as fast as you can be and keep getting faster. You can't change the world if you're held back by your typing ability, or fighting your editor, terminal tools, browser, ticketing and design software, infrastructure, or team. Omit needless actions.
Find the 'why'. Understanding the 'why' separates followers from leaders. Why are we adding this feature? Not because a tool or blog post told us to. We're adding it because it improves the customer experience, increases acquisition or conversion, or makes the product more robust. Find it in each thing you do, and if you can't, push back.
Try to learn something every day. Be curious enough to learn something every day and document it. It can be tiny, like: "Here's what fg
stands for." Consistent little steps are how great engineers become great.
Fight to work on big things. When presented with the option of working on something big, like a new app or major new feature, or doing anything else, prefer the big thing. Yes, it's risky, but you'll learn more, gain ownership, build patterns, have visibility, and context switch less. Dodge busywork.
Fight to ship. Shipping tells you what matters. Before shipping, everything is theory and scope is free. After you ship, everything is clearer and scope is expensive. There is always an argument against shipping. Be making the argument to ship.
Get a little bit good at everything in your domain. If you're a backend web developer, get decent at HTML, CSS, JS, the database beyond the ORM, project management, design, leading the meetings that you're a part of, demoing, and talking to stakeholders. Nobody will push you to do this and it takes time. Engineers who do this are more self-sufficient and have strong, independent opinions.
Be testing. Great engineers are always thinking about automated testing. Can we write one? What's the right level to test? Is this testing the right thing? Does it justify its overhead? Why didn't it catch this? How could this have failed faster? If you're refactoring without tests, you aren't refactoring– you're rolling a dice that something will break.
Writing is thinking. Almost every great engineer I know writes a lot. Internal chats, forums, newsletters, blogs– they're always producing a high-value learning exhaust. To them, writing isn't a distraction, it's the best tool to expose half-baked reasoning.
Make audible predictions. When debugging, stop and say out loud what you think will happen before taking an action. Then acknowledge if you were right or wrong and what surprised you. This moves you from reacting to taking a stand and owning your mental models.
Avoid hasty abstractions. It's better to duplicate something or be a little verbose than prematurely abstract. On unfamiliar ground, wait longer to abstract than seems reasonable. It's frustrating to wade through a series of clean, elegant abstractions only to conclude that the foundational idea is bad.
Don't stay stuck. Realize when you're stuck and ask for help. It's a call only you can make. Great engineers make it quickly.
Pay for good tools. While many good tools are free, some of the very best are not. Would you pay $40 to be twice as fast at a routine job? This kind of tradeoff presents itself often, and many engineers will reject it.
Have strong opinions, loosely held. When it comes to your opinions, which are invaluable, find the sweet spot between caring a lot about doing something a certain way and being curious that you might be wrong. Smart engineers change their minds when presented with new information. Ask "What's wrong with this idea?" to find flaws in your ideas first.
Most problems are people problems, which are the hardest problems. An application that's hard to set up is a people problem: people let the documentation atrophy, delayed upgrading libraries until it was risky, and built an organization where you don't know who to ask for help and nobody is available. A library can't solve these problems, but a leader can.
Thanks to Josh Branchaud for reviewing this post.