2026-03
How do I work with AI in a smart way as a developer
A quick note on how I use AI as a developer staying in control, writing better code, and avoiding the “vibe coding” trap.
Valentin Afonso
Fullstack developer
AI is now part of my daily workflow as a developer. But I often see a gap between two approaches:
- people who “vibe code” and let AI drive everything
- and developers who use AI as a tool, not as a replacement
So I asked myself:
Where’s the line between a vibe coder and a developer?
This is a quick note on how I try to use AI in a controlled, efficient, and sustainable way.
Create Everything, Break Nothing
One of my main rules is simple:
Create everything, break nothing.
As a developer, I want to be confident that anything generated by AI:
- doesn’t break existing features
- doesn’t introduce unnecessary code
- respects the project’s standards and best practices
That’s where testing becomes critical. I rely a lot on tests to validate AI-generated code, especially when making changes across existing features.
My approach
- I use
vitestfor testing - I try to cover critical logic before making changes
- I validate outputs instead of trusting generated code blindly
import { describe, it, expect } from "vitest";
describe("sum", () => {
it("should add two numbers correctly", () => {
expect(sum(1, 2)).toBe(3);
});
});
Of course, AI can also help generate tests (with tools like Claude Code or Cursor), but I still:
- review them
- adjust them
- make sure they actually test something meaningful
This naturally leads into a TDD-like mindset (Test-Driven Development), which I’ve found really effective when working with AI. (I’ll probably write a dedicated article about my approach to TDD.)
Step by Step — Setting Rules & Good Practices
Another key difference I see:
- A developer guides the AI
- A vibe coder follows the AI
I always try to bring my experience, my product understanding and my architectural decisions into the process.
AI is great at execution, but it doesn’t always understand long-term vision and doesn’t care about consistency unless you enforce it. So instead of prompting randomly :
- define rules
- structure my project
- guide the outputs step by step
AI becomes an assistant, not a decision-maker. (I’ll go deeper into this in another article: My Approach to Using Cursor and AI Agents in my workflow)
The Importance of Context
Something I’ve learned the hard way:
Context matters more than prompting.
A vibe coder will often focus on writing better prompts. Personally, I focus more on:
- providing context
- structuring information
- giving constraints
The more context the AI has: the better the output & the more consistent the results. I try to include things like:
- existing code
- project structure
- conventions
- expected behavior
Also, defining clear rules upfront allows me to:
- avoid repeating myself
- reduce input tokens
- get more predictable outputs
Again, this ties into how I use tools like Cursor and AI agents in my workflow: My Approach to Using Cursor and AI Agents in my workflow
Code Review Is Not Optional
This is probably the biggest mindset difference.
For a vibe coder AI is the developer, for me AI is more like a junior developer (even if sometimes it’s better than me).
And like with any junior dev:
- I review the code
- I question decisions
- I validate correctness
Code review is not optional, it’s part of the process. Yes, you can delegate code review to AI agents (again, with tools like Claude Code or Cursor), but I still read the code myself, make sure it aligns with my expectations and every check edge cases.
Final Thoughts
AI is incredibly powerful—but only if used correctly. The difference isn’t the tool. It’s how you use it.
What I try to do:
- stay in control
- rely on tests
- provide context instead of just prompts
- review everything
I don’t try to code faster at all costs. I try to code better, with AI as a multiplier—not a crutch.