The Right Way to Code with GenAI
Keep the human in the driver's seat

The rise of GenAI tools for coding has changed how many developers work. These tools can write code, explain concepts, and suggest solutions in seconds. But with this power comes an important question: how should we actually use these tools? The answer matters more than most people realize.
… study shows more than 800 popular GitHub projects with code quality degrading after adopting AI tools. … there’s a real risk that newer models will reinforce and amplify those trends, producing even worse code over time. - Rob Bowley
You are the developer, not the GenAI
The most important principle is simple: GenAI is your assistant, not the one that controls you and dictates what you should do. This might sound obvious, but it's easy to fall into the opposite pattern. When you start accepting AI suggestions without understanding them, or when you shape your work around what the AI can produce, the roles have reversed. You've become the assistant to your own tool, trapped in illusion of productivity.
A good relationship with GenAI looks like this: you decide what to build, you set the standards, and you validate the output. The AI handles the mechanical parts. Think of it like having a junior developer who types very fast but needs supervision.
Let GenAI handle the repetitive work
GenAI shines when the task is repetitive and well-defined. Writing boilerplate code, generating new code for known patterns, refactoring, converting data formats, or creating a handler for your service, these are perfect use cases. The pattern already exists, and you just need more of it.
Here's something many developers overlook: LLMs are trained on vast amounts of code from the internet, and most of that code is average at best. The AI learned from millions of mediocre examples. GenAI is better at reproducing patterns than creating excellent new ones.
The practical consequence? Write good code yourself first. Establish your patterns, your conventions, your architecture. Then let GenAI replicate what you've created. When it has your high-quality examples as context, it produces much better results than when it works from its general training alone. New GenAI tools add your existing code into the context before cooking a new one.
Grow your knowledge, don't outsource It
It's tempting to let GenAI handle everything you don't understand. Don't! Every time you accept code you can't explain, you create technical debt in your own mind. You become dependent on a tool to maintain your own project.
Instead, use GenAI as a learning accelerator. Ask it to explain or find concepts. Have it break down complex algorithms step by step. Use it to explore different approaches to the same problem. The goal is to understand more after each interaction, not less.
A developer who uses GenAI well ends up knowing more than before. A developer who uses it poorly ends up knowing less while producing more code, a dangerous combination.
Write new things yourself first
When you're building something genuinely new, like a novel algorithm, a unique business logic, your software architecture, or a creative solution, write it yourself first. Your initial version might be rough, but it will be authentically yours. It will reflect the context and your actual understanding of the problem.
Once you have working code, then bring in GenAI. Ask it to review your solution. Have it suggest optimizations. Let it simplify complex sections. This approach gives you two benefits: you maintain deep understanding of your code, and you get the AI's help making it better and you learn from it.
The reverse approach, asking GenAI to write novel code from scratch, often produces something that looks right but misses important details. The AI doesn't understand your specific context the way you do.
A surprisingly good Rubber Duck
Perhaps the most underrated use of GenAI is as a thinking partner. Traditional "rubber duck debugging" involves explaining your problem to an inanimate object to clarify your thoughts. GenAI takes this further because it actually responds.
Use GenAI to organize your thoughts before writing code. Describe the domain you're modeling and ask it to identify potential challenges. Explain a problem you're stuck on and let it ask clarifying questions. Discuss different architectural options and their trade-offs.
This kind of dialogue often reveals gaps in your thinking without any code being written at all. The AI serves as a mirror that helps you see your own ideas more clearly.
Context is everything
Here's a truth that separates effective GenAI users from frustrated ones: the quality of output depends almost entirely on the quality of context you provide. An LLM without context is like a skilled contractor who shows up with no blueprints. They might build something, but probably not what you need.
Good context means giving the AI everything it needs to understand your world. There are several ways to do this:
Plan mode before edit mode. Tools like Open Code or Claude Code offer a plan mode. Use it to discuss and validate the approach before the AI touches any files. This back-and-forth clarifies context and catches misunderstandings early.
For complex tasks, start with high-level domain context, then narrow to the specific module, then to the exact problem.Dedicated context files. Tools now support files like
AGENTS.mdin your repository. Define your architecture, conventions, and constraints once, and every AI interaction benefits.System prompts. When available, use them if necessary to establish the role, standards, and boundaries the AI should follow.
The investment in good context pays off quickly. You spend less time correcting mistakes and more time on work that matters. Strategic Domain Driven Design shines even more in the GenAI era.
The bottom line
GenAI is a powerful tool, but tools don't make decisions, developers do. Use it for repetition, not creation. Use it to learn, not to avoid learning. Let it help you think, not think for you.



