What Five Years of Writing Code Taught Me About Product
I wrote code for five years before I moved into product. The code mattered less than the habits it left me, and one of them I had to unlearn fast.

I didn't leave engineering because I got tired of code. I left because I noticed where my head went on every project.
I'd get a brief, and before I opened the editor I'd picture the person who was going to use the thing. What they were trying to get done. Where they'd get stuck. What they'd do when it broke. I'd walk through the whole path with them in my head, step by step. Only then did I start building. After a while I realized that walk was the part I loved. The building was how I got to do it.
That's when I moved into product. Solving the problem for the user mattered more to me than writing the solution. And the technical background turned out to help most exactly there, so I went deeper into it instead of leaving it behind.
This post isn't about my CV. You can read that on the about page. It's about the habits of thinking that came with me from engineering into product: the ones that helped, the one I had to unlearn and what replaced it.
Think in two tracks at once
The most useful habit is simple to describe. When I think through a product path, I think through the technical path next to it.
Say we're designing a new booking flow. On one track I'm asking product questions. Who books, from which device, what do they need to see before they commit, where do they drop. On the second track, quietly, I'm asking how this gets built. Which data do we already have. Which part touches a system nobody wants to touch. Which step looks small on a wireframe and turns into three weeks of integration work.
I don't do this to design the system. I do it so the product decision is already shaped by what's possible before it reaches the engineers.
It kills most of the back-and-forth. You know the loop. Product writes a spec. Engineering reads it and says the second half needs a rebuild of the payments layer. Product rewrites. Engineering finds a new problem. Two weeks pass and nobody has built anything. When the person writing the spec already ran the technical track in their head, the first version that lands on the engineers' desk is one they can actually build. The conversation starts at "how do we build this well" instead of "can we build this at all".
Speak both languages
The second habit is translation.
Product people and engineers often describe the same problem in different words and don't notice they agree. Product says users abandon the form at step three. Engineering says the address lookup is slow on mobile. That's one problem with two names. If nobody in the room speaks both languages, those two observations go into two different backlogs and get fixed twice, or never.
Having written code, I can hear the engineering version of a user complaint and the product version of a technical limit. I can tell a product lead why a "small" request isn't small, in terms of what it costs the user if we get it wrong. I can tell an engineer why a rough edge they'd happily ship matters, in terms of what the user is actually trying to do. That translation is a big part of the job, and it's the part nobody writes into the job description.
The habit I had to unlearn
Early on I did something that felt helpful and wasn't. I handed engineers the implementation.
I'd show up with the product problem and the technical solution in one package. Here's what users need, and here's how we should build it: this table, this endpoint, this library. I thought I was saving the team time.
I was taking the most interesting part of their work away from them. And I was usually wrong in small ways that mattered. The engineers knew the codebase better than I did. They knew which shortcut would hurt us in six months and which "clean" approach would take three times longer than it looked. When I handed them my solution, I got my solution built. Not the best one. And I got a team that was executing my design instead of owning the problem.
Knowing how to code made this worse, not better. A PM who can't code can't fall into it. A PM who can is tempted every single day.
Constraints in, implementation out
What replaced it is the split I still work by.
During product design, the technical constraints come in. I bring everything I know about how the system works, what's expensive, what's risky and how much time we actually have. All of that shapes the product decision. With the deadline we're facing and the system we've got, what's the version of this feature that solves the user's problem and actually ships?
Then the implementation goes out. I hand the engineers a product solution that works within those constraints, and the how is theirs. Which table, which pattern, which library. Their call.
The product solution is still technically informed. That's the whole point of the two tracks. But informed is a different thing from prescribed. I use what I know to choose a problem worth solving in the time we have. I don't use it to write their code for them in a meeting.
Stay in the room anyway
Handing over the implementation doesn't mean leaving.
I still sit in the engineering meetings. Not to make the decisions. To notice when something is drifting, and to give a second point of view when it helps.
The most common moment is an estimate. The team says a feature will take six weeks. Sometimes that's right. Sometimes the six weeks are driven by one piece that matters a lot less to the user than everyone assumes. Because I was in the room and I understand what's being discussed, I can ask the useful question. What's driving the six weeks? If we drop that part, or do it manually for the first month, what does it cost the user? Often the answer is a version that ships in two weeks and solves most of the problem. Sometimes the answer is that the six weeks are real and I learn something about the system I didn't know.
Either way, the conversation happens in that meeting, not three weeks later when the deadline slips. And it happens between people who both understand the trade-off, not as a negotiation between "the business" and "the tech team".
Does any of this matter when AI writes more of the code?
I think it matters more.
As AI tools take on more of the typing, the scarce skill moves. Producing code gets cheaper. Knowing which code is worth producing, what will be expensive to change later and where the real risk sits gets more valuable. That's the second track. A PM who can run it doesn't need to write the code. They need to know enough about how systems behave to make a product decision that survives contact with engineering, and now with the tools engineering uses.
If you're a developer thinking about product
Developers ask me if they should switch. I don't think the real question is if you can code well enough to bring something to product. If you've shipped real software, you can.
The question is what you enjoy more: the problem or the solution. If the part you love is the build itself, stay. Engineering needs people like that, and it's a great job. If the part you love is the moment you picture the user and walk the path with them, and the code is how you get there, product might be where you belong.
Bring the technical habits with you. Think in two tracks. Translate. Stay in the room. And leave the implementation to the people who'll own it.
If you want to talk about moving from engineering into product, or about how product and tech teams can stop talking past each other, get in touch.
Sources
This post is first-party. It comes from my own work as a developer and then as a product lead, and it cites no outside studies or statistics.


