AI wrote a function for me last week It worked Tests passed Edge cases handled I shipped it.
But something bothered me - not enough to rewrite it not enough to flag it in review Just enough to leave a small discomfort I couldn't name.
The code was correct It wasn't good.
Variable names were vague in a way that was technically fine but practically annoying The logic was nested one level deeper than it needed to be There were three places where a comment would have explained why not just what - and none of them had one The function did exactly its job but reading it felt like reading an instruction manual written by someone who had never used the product.
AI writes code that works It rarely writes code that sings.
This isn't a complaint about bugs or hallucinations or incorrect outputs It's about a different gap - the gap between "correct" and "elegant" Between no one can complain about this and this is genuinely well-made.
Here's why that gap exists why AI can't cross it and why it matters more than most people are willing to say out loud.
What Good Enough Actually Means
Let's be specific. "Good enough" code:
✅ Passes all tests
✅ Handles the happy path correctly
✅ Covers the common edge cases
✅ Runs without crashing
✅ Does exactly what was asked
It does the job Nobody will complain The ticket gets closed The feature ships.
But "good enough" also means:
❌ Hard to read on first glance - you have to trace it before you understand it
❌ Variable names that make you pause for half a second every time
❌ Nested logic that could be one level flatter without losing any clarity
❌ No comments explaining why a decision was made only what is happening
❌ Structured in a way that makes the next change slightly harder than it needed to be
The AI optimized for correctness It didn't optimize for understanding It generated code that satisfies the requirements It didn't generate code that respects the reader.
And here's the quiet danger: most of the time good enough is genuinely fine Not every function needs to be poetry Not every script needs to be a masterclass. But when every function is just barely passable when the entire codebase is optimized for no one can object to this rather than this is actually good - something shifts.
The baseline lowers Slowly And you stop knowing what great even looks like.
What Great Code Looks Like
Great code isn't just correct It has specific qualities that go beyond passing tests:
Readable. You understand it on the first read not the third You don't need to trace execution to follow the logic.
Self-documenting. Variable names tell you what's happening Function names tell you why You could read it without knowing the surrounding context and still understand the intent.
Simple - not simplistic. The simplest thing that could work chosen deliberately Not the first thing that came to mind.
Surprising in a good way. There's a solution so clean it makes you smile Not clever for the sake of being clever just genuinely the right approach arrived at through judgment.
A joy to change. Adding a feature doesn't feel like surgery The structure anticipates the next developer.
Great code feels crafted Not generated There's a difference - and you can feel it when you read it even if you can't always articulate why.
AI can't write great code Not because it's not technically capable Because great code requires taste It requires judgment A sense of what good looks like beyond correctness - what's appropriate what's overkill what's elegant for this specific situation in this specific codebase.
Taste comes from experience From having read thousands of functions From having been burned by bad code From having fixed bugs at 2 AM in code that worked but was structured wrong in a way that made everything harder.
AI has processed millions of functions But it hasn't felt any of them.
The Three Gaps AI Can't Cross
1. The Taste Gap
AI knows what works It doesn't know what's good Taste isn't pattern recognition it's judgment It's knowing when a familiar pattern is actually a bad fit for this specific situation even if it technically solves the problem It's knowing when the right solution would make the next developer's life harder.
AI can approximate taste by matching patterns from high-quality training data But matching patterns isn't judgment It's mimicry.
2. The Context Gap
Great code fits its context The same solution might be excellent in one codebase and genuinely terrible in another - depending on the team's conventions the performance constraints the expected lifetime of the code the experience level of whoever will maintain it.
AI generates based on the prompt not based on the specific constraints of your project It doesn't know that your team hates clever abstractions It doesn't know this service gets called 10 million times a day It doesn't know this code will be owned by someone who joined last week.
3. The Consequence Gap
AI has never been paged at 2 AM It's never had to debug its own code six months after writing it It's never felt the cost of a bad abstraction the hours spent untangling something that seemed reasonable at the time.
Great code comes partly from knowing what not to do And that knowledge comes from pain from specific memorable experiences of code that bit back AI has no pain No scars No I'll never do that again moments
These three gaps aren't bugs in the technology They're features of what it is AI optimizes for correctness Greatness requires something that correctness alone can't produce.
Why This Matters
Good enough is completely fine for throwaway scripts For one-off automation For prototypes that will be deleted For functions no one will maintain.
But when good enough becomes the default when every function in a production codebase is just passable the codebase quietly becomes something else. Harder to change Harder to understand Harder to debug. Harder to reason about.
You stop knowing if the code is actually correct or just looks correct.
The real cost isn't performance It's comprehension Bad code hides bugs. Good code reveals them. Great code structures things so bugs are harder to introduce in the first place.
Every good enough function is a small tax The AI saved you ten minutes now. That structure will cost you an hour in three months when you need to change it Multiply that across a codebase where everything is just barely passable.
The compound interest on good enough is expensive.
What I'm Doing Differently
I'm not quitting AI That's not the answer and it's not what I want.
But I'm changing how I use it:
I treat AI output as a first draft. Not the final answer A starting point that I'm responsible for finishing The AI writes the code I make it mine.
I ask: Would I approve this if a junior wrote it? Same standards Same code review The source of the code doesn't change the bar it has to meet.
I refactor one function per AI-generated PR. Just one Make it simpler Add the comment that explains why Rename the variable to something that doesn't make me pause Small acts of craftsmanship consistently.
I remember that good enough compounds. Today's it's fine ship it is next month's why is this so hard to change? The feeling of lowering standards is barely noticeable in the moment The cost shows up later.
Will these habits make AI-generated code great? No But they stop me from forgetting what great looks like. And that matters.
One Question
When was the last time you saw AI-generated code that made you say - not that works not that's fine - but that's actually clever?
A solution that surprised you That you wouldn't have written that way yourself but immediately recognized as better.
If you have an example share it in the comments I genuinely want to see what's possible at the top end.
I'll go first - with the one piece of AI-generated code that actually impressed me.
Your turn. 👇
Top comments (5)
I think it's not so good because it's "smooth" - there are no variables with strange names, no functions that are not clear why they are needed, and of course the style is the same
Ember smooth as criticism is a fascinating angle Smooth usually means good Here smooth means predictable Safe The AI never makes weird, interesting choices Strange names, unclear functions those sometimes come from human leaps AI doesn't leap. It walks the well-worn path.
Smooth is safe Safe is good enough Good enough is never great.
Thanks for this lens. 🙌
Im noticing the same. Its always just enough to pass but lacks the creativity you see with a human developer.
Just enough to pass perfect phrase Not wrong Not broken Just adequate Adequacy is fine But the hidden cost shows up later when just enough makes the next change harder than it should be.
Creativity isn't flashy It's seeing a path the AI missed.
Thanks, Evan. 🙌
Great read! Really explains why AI code feels like a solid junior developer gets the job done but lacks that spark of creativity and deep architecture thinking.