I have built features that were technically elegant and completely useless. I have spent weeks optimizing systems that nobody cared about. I have shipped products that solved problems I invented in my head while the actual problems customers had went unaddressed. Every engineer who has been building long enough has a version of this story.
The gap between what engineers build and what customers need is one of the most persistent and expensive problems in software development. Design thinking is the discipline that closes that gap. And in my experience, it is the skill that separates engineers who build great products from engineers who build great code.
The Engineer Brain and Why It Works Against You
Engineers are trained to solve problems. Give us a problem, we will solve it. The issue is that we are so good at solving problems that we often skip the step of verifying that we have identified the right problem in the first place.
We see a slow API and immediately start thinking about caching strategies. We see a confusing UI and immediately start thinking about redesigns. We hear a customer complaint and immediately start thinking about solutions. The instinct to jump to solutions is deeply ingrained, and it is the source of most wasted engineering effort.
Design thinking is fundamentally about resisting that instinct. It is about staying in the problem space longer than feels comfortable, understanding the problem more deeply than seems necessary, and only then moving to solutions.
The Five Stages and What They Actually Mean in Practice
Empathize: This is not reading user research documents. It is talking to actual customers, watching them use your product, and listening without an agenda. The goal is to understand their world — their workflows, their frustrations, their goals, their constraints. Not to validate your assumptions. To challenge them.
I make it a practice to talk to at least two customers every week. Not to pitch features. Not to gather requirements. Just to understand what their day looks like, what slows them down, what they wish was different. The insights that come from these conversations consistently surprise me, and they consistently change what I build.
Define: This is where you synthesize what you learned in the empathy phase into a clear problem statement. Not a solution statement disguised as a problem statement. A genuine articulation of the problem from the customer perspective.
The difference between a good problem statement and a bad one is enormous. A bad problem statement: users need a faster checkout flow. A good problem statement: users who are purchasing on mobile abandon checkout when they have to re-enter payment information they have entered before, because the friction of re-entry is higher than the value of completing the purchase in that moment. The good problem statement points toward solutions. The bad one just describes a symptom.
Ideate: This is the brainstorming phase, and the rule is that judgment is suspended. Generate as many solutions as possible before evaluating any of them. The goal is quantity, not quality. The best ideas often come from combining or building on ideas that seemed impractical at first.
I run ideation sessions with cross-functional teams — engineers, designers, product managers, and sometimes customer success people who talk to customers every day. The diversity of perspectives consistently produces better ideas than any single discipline would generate alone.
Prototype: Build the smallest possible thing that tests your core assumption. Not a polished product. Not a complete feature. A prototype is a learning tool, not a deliverable. It should take hours or days, not weeks.
The most valuable prototypes I have built were not code at all. They were mockups, clickable wireframes, or even paper sketches. The goal is to make your idea tangible enough that customers can react to it, not to build something production-ready.
Test: Put your prototype in front of real customers and watch what happens. Not what they say — what they do. People are notoriously bad at predicting their own behavior. They will tell you they love a feature and then never use it. Watch them interact with the prototype and pay attention to where they get confused, where they hesitate, and where they succeed.
Applying Design Thinking to Technical Decisions
Most engineers think of design thinking as a product discipline. I apply it to technical decisions as well, and it has changed how I approach architecture.
When I am considering a significant technical change — migrating to a new database, refactoring a core service, adopting a new framework — I go through the same process. Who are the stakeholders? What problem are we actually solving? What are the constraints? What are the alternatives? What is the smallest thing we can do to test our assumptions before committing?
This approach has saved me from several expensive mistakes. The migration that seemed obviously necessary turned out to be solving a problem we did not actually have. The refactor that seemed urgent turned out to be less impactful than a much simpler change. The new framework that seemed like the right choice turned out to have trade-offs that were not apparent until we prototyped with it.
The Customer Interview as a Core Engineering Skill
I believe every engineer should know how to conduct a customer interview. Not because engineers should replace product managers or user researchers, but because the engineers who understand customers build better software.
A good customer interview is not a survey. It is a conversation. You are not asking customers what they want — customers are notoriously bad at articulating what they want. You are asking them about their current behavior, their current frustrations, and their current workarounds. The solutions are your job. Understanding the problem is a shared responsibility.
The questions I always ask: Walk me through how you currently handle this. What is the most frustrating part of that process? What do you do when that happens? How often does this come up? What would have to be true for this to not be a problem anymore?
The last question is particularly powerful. It forces customers to articulate the underlying need rather than a specific solution, and it often reveals constraints and requirements that would not have surfaced otherwise.
Measuring Whether You Solved the Right Problem
One of the most important habits I have developed is defining success metrics before building a feature, not after. Before we start building, we ask: how will we know if this worked? What metric will move? By how much? In what timeframe?
This discipline does two things. First, it forces clarity about what problem we are actually solving. If you cannot define what success looks like, you probably do not understand the problem well enough to solve it. Second, it creates accountability. After the feature ships, you check the metrics. If they did not move, you learn from that and adjust.
Too many engineering teams ship features and never look back. They move on to the next thing without ever knowing whether the last thing worked. This is how you end up with a product full of features that nobody uses.
The Transformative Shift: From Feature Factory to Problem Solver
The most significant shift I have seen in engineering teams that adopt design thinking is the move from being a feature factory to being a problem-solving organization. A feature factory takes requirements and builds them. A problem-solving organization understands customer needs and figures out the best way to address them — which is sometimes a feature, sometimes a process change, sometimes better documentation, and sometimes doing nothing.
This shift requires trust between engineering and product. Product needs to trust that engineering will engage seriously with customer problems, not just ask for requirements. Engineering needs to trust that product will incorporate technical constraints into problem framing, not just hand over specs.
When this trust exists, the quality of what gets built improves dramatically. Engineers who understand the problem they are solving make better technical decisions. They know which constraints matter and which do not. They can identify simpler solutions that product might not have considered. They can push back on requirements that do not actually address the underlying problem.
Conclusion
Design thinking is not a process you follow. It is a mindset you develop. It is the habit of staying curious about problems longer than feels comfortable, of questioning your assumptions before acting on them, of testing ideas cheaply before investing in them fully.
The engineers who build the best products are not the ones with the deepest technical knowledge. They are the ones who combine technical skill with genuine curiosity about the people they are building for. They understand that the goal is not to write great code — it is to solve real problems for real people. The code is just the means.
Start talking to your customers. Not to gather requirements. To understand their world. Everything else follows from that.