History doesn’t move in a straight line. I remember growing up in the seventies and eighties, and even as a child understanding that the world could end at any moment due to forces beyond my control. A computer might misinterpret sunlight on high altitude clouds, a world leader might make a stupid joke, and the world could simply… end. Adults didn’t try to hide us from the reality, and in retrospect it almost feels like they were all trying to outdo themselves with increasingly graphic depictions of how it might happen, or what it would look like if it did.
And then one day, with no warning, it was over. There was lots of clean up, and there were all sorts of disastrous consequences (many of which we’re still living with), but for the most part we’ve stopped worrying about all life ending in a flash of light. It turned out that we’d been living through a special period, starting in 1945 and ending in 1989, in which the world went through a unique transformation. It started one way, then changed, then changed again. Of course, this happens all the time, in big and little ways, mostly without us noticing. The zero interest rate period lasted effectively from December 2008 to March 2022, and had a massive distorting effect on venture capital and the startup economy. NFTs lasted from 2017 to 2022, then disappeared without a trace. So it goes.
Which brings us to software engineering. Because while the technologies and techniques changed, project management went through major transformations, and corporate models, funding, and salaries have done head flips, software engineering itself – as a career and a discipline – has remained fairly stable over the past half century. Which was nice while it lasted, but of course AI is throwing everything into chaos. We had a good run, but the world is changing beneath our feet.
Anyway, you know all of that. What you don’t know – what no one knows – is how it’s all going to turn out. And while there are plenty of well-researched articles on how the economics of the biggest AI companies don’t make sense, I think we can agree that whether or not they collapse under hundreds of billions of dollars of debt and comparatively imperceptible revenue, the technology is here to stay. So with that in mind, the question is, what happens next?
But first, a note
It is difficult to get a man to understand something, when his salary depends on his not understanding it. –Upton Sinclair
Before I get into it, I want to address the foundational problem of ethics.
Let’s just get it out there. AI is a useful tool. Also, it was built through the largest theft of labor in human history and is accelerating climate change through an unprecedented consumption of water and electricity. Both of these things can be true, and pretending otherwise isn’t helpful.
I’m not going to tell you that AI is an ethically neutral tool, or that you’re a bad person for using it. We all choose our battles. The reason I’m writing this post is that a number of people – mostly early-career developers – have been asking me what they should do. They started coding because they enjoyed it, and while the initial rush of super-charged autocomplete was a fun sugar high for a while, they’re staring down forty years of a career pushing the same button over and over. No learning, no growth, no intellectual challenge, none of the joy that got them into writing code in the first place. And while there are many, many things I don’t know, I think I have some ideas that can help stave off despair.
What we know now
Right now, people are using AI for everything. And so, like transforming the American diet with trans-fats, putting asbestos into everything, or flooding the world with microplastics, we’ve created a world-wide natural experiment into what AI can and can’t do. Ten years from now we’ll know for sure. Ten years from now we’ll be able to agree that AI is very good at A and B, and a horrible choice for Y and Z. In the meantime, we get to FAFO.
Still, there are a number of things we already understand about how LLMs work, and I think we can draw some reasonable conclusions. First of all, LLMs write spaghetti code. They don’t follow software engineering principles, don’t modularize, don’t reuse. They blast out multi-thousand line PRs not because those are the best possible solutions, but because that’s how they work.
LLMs are good at throwaway prototypes and bad at delicate modifications. They can find security bugs – which is impressive! – but do a bad job of fixing them. They’re a bad choice for developing cryptography, compilers, or anything where correctness, speed, resource consumption, compliance, operational stability, security, or idempotence are critical.
LLMs are good at generating mostly correct documentation for existing code, explaining how a code module probably works, generating boilerplate, and writing code in which the difficulty is mostly due to a large set of keywords or arcane rules (terraform, css). They can be prompted to create high quality small- to medium-sized functions. When used to create more extensive functionality, they generate massive amounts of slop.
You don’t need deep operational knowledge of a web page’s CSS, but you do need to be able to respond to operational outages at 2AM with people who can triage, debug, and fix major systems. AI can help give you answers at 2AM, but is bad at creating code that can be understood by the humans responding to the outage.
We can keep playing this game, but you get the point. If “good enough” is good enough – if you need to understand something, analyze something, come up with a reasonably accurate guess quickly, or build something small or that doesn’t have to be perfect, then AI is probably fine.
On the other hand, there are some systems – compilers, credit card processors, accounting systems, etc. – for which correctness is a core requirement. A compiler that generates accurate, performant, optimized code 99.9% of the time is worthless. There are low-level systems and platform tools (like hardware drivers, databases, DNS, message queues) that need to be correct, performant, and attentive to resource usage. There are systems with complex operational and security requirements, intricate data orchestration, or data-driven decision-making that demand precision and accuracy. When results matter, you can’t rely on systems that are “good enough.”
It’s worth remembering that you aren’t running vibe-coded apps on top of vibe-coded operating systems, vibe-coded databases and network services, using machine code generated by vibe-coded compilers and linkers, containerized by vibe-coded containerization tools, interacting with hardware via vibe-coded device drivers, and communicating over the internet using vibe-coded cryptographically secure network protocols. LLM-generated apps are sand castles built on a vast bedrock of infrastructure built by humans over decades. The only reason they work is that the foundation is solid.
The future
I think we can agree that LLMs are getting better at producing code that passes unit tests, and whose output meets a specification. At the same time, the overall quality of AI-generated code remains low. The orchestration layer and harnesses are getting better at interpreting prompts, working in parallel, analyzing code, choosing models for different tasks, and so on, but the generated code still sucks.
This, then, is the key question. Fast forward ten years: do you believe that there will still be code that humans have to write? Do you believe that the AI code generation mechanism will have improved to the point that it follows software engineering principles? Will it converge to the level of quality that a great software engineer could generate, just faster? Because software engineering principles exist for a reason. They aren’t nice-to-haves, or a sop to human frailties. They exist because big-O, code re-use, modularization, design patterns, thread safety, idempotence, re-entrance, byzantine fault tolerance, etc. etc., are necessary for systems that are secure, performant, correct, maintainable, and optimized. If LLMs can’t encode these principles, then they will never be able to build certain types of software.
There are plenty of AI boosters who believe that LLMs will be able to make the leap from generating their current level of slop to creating correct, performant, large-scale systems. There are other AI boosters who believe that it doesn’t matter – that as long as the unit tests pass and the output matches spec, then the quality of the underlying code is irrelevant, and that slop is perfectly fine. You have to decide if you believe either of these statements. If you do, then there’s no reason for you to continue reading to the end of this post.
But if you don’t – and I would suggest that nothing in what we’ve seen so far suggests that LLMs will magically transcend, or that slop can achieve all goals – then there will still be a need for engineering skills in the future. There will be a need for engineers who can use AI, and who are also able to expertly read, write, and understand code.
Not only will there be a need, but we will see a severe bifurcation in the engineering population. On the one hand, there will be people who used to be engineers, but deskilled to the point that they’re only able to use AI (ask any manager what their skills are like after not coding for ten years). On the other hand, there will be people who are still able to write code, understand and decompose complex technical problems, create deep designs, and build systems that LLMs fundamentally can’t. The ex-engineers will be completely commoditized, and the comparatively small number of engineers who somehow managed to maintain and build their skills will be in high demand.
This is my thesis: that in ten years this will have all shaken out. Conventional wisdom will include an understanding of what AI can and can’t do, and being able to act on that understanding will be part of what makes a senior engineer. I can use AI for this, but I must understand the code for that. I can vibe-code a throwaway prototype, I should build this subsystem one function at a time using AI, and I need to meticulously write this critical section by hand. We’ll look back on today’s marketing claims the same way adults look back at arguments over whether Mighty Mouse could beat Superman,1 shake our heads at how stupid it all was, and go about our business.
If you believe this, if this makes sense, then you know that maintaining your engineering skills is critical to maintaining your value in that future world. This creates a problem, because we’re currently in the donut hole between now and then. Right now, everyone is being encouraged to use AI for everything, and we’re going through a civilization-wide engineering skill extinction event.
So, if you’re a professional software engineer using AI, and want to continue to grow while preventing your skills from atrophying, then what can you do about it?
Taking Control
I don’t know what your workplace is like, and I can’t tell you what’s safe. I’m fortunate to work at a company where AI use is encouraged, but not mandated. I know of other companies where AI usage metrics are used to determine who gets laid off. There’s a lot of toxic cargo culting out there.
As an individual contributor trying to maintain or build your skills, this poses a problem. In the old days2, engineering ran as an apprenticeship program. Junior engineers worked on progressively more complex projects, mentored by senior engineers who reviewed their code and technical designs, gave advice, and generally supported them as they grew. It didn’t always work out (mentoring skills vary widely), but at least you were coding every day.
In the new system, you’re pushing the button repeatedly – generating value for the company (maybe), but not developing your own skills. Your job has transformed from a paid apprenticeship to a permanently junior spot on the assembly line. So what do you do?
There’s no silver bullet. To build any skill you need to engage in deliberate practice. You need to write code (a lot of it), and you need to have that code reviewed and corrected by someone who knows more than you do. You need to read about advanced techniques, implement them yourself, then see what happens when your code runs into actual users. All the careful design and automated tests in the world won’t prepare you for the utter depravity of real production usage.
The best I can offer is that you need to carve out some part of your day – as much as you can – and use it to write code without AI. Your company benefits from your labor, but if you aren’t growing then all you’re getting in return is money. Don’t get me wrong – we’re all working for the paycheck – but if you don’t get promoted, don’t learn anything new, don’t progress in your career, then you’ll be stuck pressing the same button for the rest of your life.
The most effective way to do it, is to just do it. –Amelia Earhart
Maybe you can keep the interesting parts of your projects to yourself. Maybe you can create your own technical designs instead of prompting the machine. Maybe you can start a personal project at home. Every situation is different, but the one common element is that you can’t get in shape without exercise. To get better at coding, you need to write code.
In a lot of cases, your worst enemy might be yourself. Once you’re used to pushing the magic button, it can be frustrating and feel pointless to do it by hand. One piece of advice I can give is to make it a little harder for yourself to use AI. Log out after each use. Close the window. Force yourself to jump through hoops. Make yourself do it the hard way first. Anything helps. If you can introduce even small barriers, you’ll be a little less likely to solve every problem with AI, and you’ll be giving yourself a shot at doing the work yourself.
Managering
For the managers out there, let’s do a gut check. Do you think any of this is important? Personally relevant? Maybe you think that your engineers aren’t losing their skills. After all, you started with stars and raised the bar on every hire. Your team is special, not like all those other teams. None of your engineers are complaining, and AI is making everyone incredibly productive, right? And besides, you have your quarterly OKRs, your boss is looking at your team’s token usage, and you have enough on your plate without worrying about something the rest of the industry is telling you doesn’t matter.
It’s much easier to go along to get along – you’re incredibly busy, and deciding not to believe, letting it be someone else’s problem, or simply not caring are all huge time savers. And even if you did want to do something, it’s easy to feel helpless in the face of epochal change. What can you, an individual, do that could possibly make a difference? I feel you.
It sounds cliché, but the first step is admitting that there’s a problem. If you don’t think that any of your engineers are going through an existential crisis about their future in an industry that’s extinguishing their skills, halting their career progression, removing the joy they felt in their work, and threatening mass layoffs, then I would gently suggest that you might not be paying attention. Some of them love AI, sure, but many are afraid of losing their jobs if they admit to anything less than full-throated enthusiasm. Depending on the workplace and your relationship with your team, you might not be able to get an honest answer. You yourself might not feel safe raising the topic!3
Having said so, creating a safe space in which to have the conversation is essential. You need to know what your team is thinking, and to look for opportunities that won’t put them at risk. This is a hard problem! It isn’t realistic to create a curriculum from scratch to take engineers from junior to senior in the absence of real-world practice. We can and should lean into pre-existing materials (books, online courses, etc.), but if we want our engineers to maintain and grow their skills, they’re going to have to write actual code. One-off activities aren’t going to do it. We need a new system to replace the one we lost.
In the book Atomic Habits, James Clear talks about the importance of focusing on systems, not goals. Having a goal of helping your engineers won’t get you there. The most important thing is to find a step you can take, then another step, and another, and to keep on going. The size of each step isn’t as important as just not stopping.
- If you get this reference, then you should probably schedule your shingles shot. ↩︎
- You know, two or three years ago. ↩︎
- Seriously, how did we get here? ↩︎
#zuzai – no part of this post was written with AI
