AI removed the natural friction of writing code. The result isn't that building became easier—it's that complexity arrives faster than your mental model can update.
The Speed Limit
AI makes it possible to write software faster than ever.
But there's a catch: you can now build a system faster than you can understand it.
Traditionally, writing software forced you to slow down. You had to understand enough of the language, syntax, and system architecture to make things work. Even when copying from Stack Overflow, you still had to figure out how to integrate it.
That friction wasn't always pleasant, but it served a purpose. You learned along the way.
AI removes much of that friction:
- You can implement entire components without knowing the language deeply.
- You can produce hundreds of lines of code in seconds.
- You can build a working application without fully grasping how every piece works underneath.
In some ways, development has become easier. In others, it's become harder—because the code can grow faster than your comprehension.
Complexity Arrives Faster
When building something small, architectural decisions can feel unnecessary:
- Why introduce an interface when you can just call a function?
- Why separate components when everything fits in one file?
- Why draw an architecture diagram when you can hold the entire application in your head?
Those are reasonable questions for a trivial script. But as the system grows, the trade-offs change.
Components begin depending on one another. Changes in one place break several others. New features become harder to implement. Eventually, even figuring out where to make a change becomes an engineering bottleneck.
With AI, you can reach that chaotic tipping point much faster.
The code might run. But as you spend more time explaining the system to the AI, reviewing unexpected modifications, and correcting earlier shortcuts, the speed advantage starts disappearing.
Design Helps You Keep Your Bearings
I experienced this firsthand while building Ready-Mail, an application that processes customer records for direct-mail campaigns.
Before implementing much of the application, I established a big-picture architecture and an end-to-end data flow. Nothing overly academic—I just wanted to know what components existed, what each was responsible for, and how information moved between them.
From there, I could design individual components as needed. And something interesting happened as the application scaled.
There were moments when I genuinely lost track of the larger system while deep inside a component solving a specific problem. Instead of asking AI to re-explain the entire repository, I returned to the diagrams:
Where am I? What comes before this? What comes after? What depends on what?
Within minutes, I could orient myself and continue. The architecture wasn't just organizing the code; it was organizing my thinking.
Interfaces Let You Move Without Knowing Everything
Once I understood the broader system, I didn't need every implementation detail figured out before moving forward.
One of the most useful decisions I made was establishing interfaces before implementing everything behind them. For example, I defined a storage interface long before needing a complete persistence layer.
- I could use mocks to test the pipeline.
- I could develop other components without committing to database schemas I hadn't settled on yet.
- When I eventually needed storage, its boundary was already waiting.
The same structure made parallel development possible. At one point, I was working on the data model while an AI agent worked on the web interface. Because the components had defined contracts, neither blocked the other.
As the architecture matured, my instructions to the AI became simpler and more precise:
- Create this component.
- Connect it to that interface.
- Add retries and exponential backoff to the enrichment process.
- Improve logging through the existing event mechanism.
I didn't have to re-explain the system every time. The responsibilities were already established.
But Designing Everything Is Another Trap
There's a temptation to take this too far. If architecture makes implementation easier, why not design everything before writing any code?
Because sometimes you don't know what you need yet.
Implementing a complex abstraction too early can be just as expensive as implementing it poorly. You generate the code, test it, and discover your assumptions were wrong—now you're updating the implementation and everything depending on it.
AI makes those changes faster, but it doesn't make them free.
What worked was establishing enough structure to move forward while intentionally deferring decisions that didn't need to be made yet. The goal wasn't to predict every requirement upfront, but to create a system I could continue developing as my understanding improved.
The Engineering Still Belongs to You
I don't think AI requires an entirely new form of software engineering.
What changed is how quickly you can experience the consequences of ignoring its core principles.
For me, the goal isn't to write every line of code myself. It's to maintain enough understanding and control that I can explain the system, change it, and continue developing it without becoming dependent on AI to tell me how my own application works.
AI makes it easier to build software. It doesn't automatically make it easier to engineer software.
Top comments (0)