Programming Tutorials Are Dead. Now What?
A week ago I wrote Programming Tutorials Are Dead.
The title was supposed to be annoying. Tutorials obviously still exist, and I still read them. Some of the responses pointed out two things I agree with: developer education was already getting harder to sell before LLMs showed up, and replacing mediocre tutorials with AI slop obviously is not an improvement.
The more useful question is what I actually want instead if the old workflow is breaking down. I am on both sides of that problem. I sell technical material, but I also buy and read a lot of it.
I still want to learn from people
Section titled “I still want to learn from people”I still like books. Reading one makes me sit with somebody else’s thinking longer than asking a model for an answer, and sometimes that is exactly what I want.
Video is harder for me. I regularly look at a 45-minute technical video and think, “I wish I could know what this person said without spending 45 minutes finding out.” The same thing happens with a huge PDF when the part I care about is buried somewhere in the middle.
None of that means I want a model to generate a worse version of the material for me. The change happens after I find something useful.
If an article overlaps with a system I already built, I usually open an agent in that repo and ask:
How close is what I already have to this?
Or:
How would this fit what is already here?
That has become a normal part of reading technical material for me. Most content still stops right before it.
The author explains the idea, gives me code, maybe includes a sample app, and then I am supposed to translate all of that into my application. That translation used to be a large part of the work. Now it is one of the things coding agents are very good at.
Code got cheap faster than decisions did
Section titled “Code got cheap faster than decisions did”Billing is an easy example because there are a lot of decisions hiding behind something that sounds simple.
Ask a capable agent:
Add Stripe billing to my Rails app.
It can get surprisingly far. It can add Checkout, wire up Pay, create routes, handle webhooks, write tests, and probably make the page look decent while it is there.
It also has to answer a bunch of questions you did not put in the prompt. What gets billed: the user or the account? Is Stripe the source of truth for whether somebody gets access? What happens during a failed payment? Can a webhook grant access directly? What happens when a customer has an old price that is no longer for sale? What is supposed to happen if two billing operations overlap?
The agent is going to answer those questions somehow. The Stripe API call is cheap now; accidentally building two definitions of paid access into the application is still expensive.
If somebody has spent years learning which billing decisions become painful later, I want the benefit of that experience. I want to know what they tried, what broke, which boundary they settled on, and what should still be true after an agent adapts the implementation to my application.
Cheap code generation does not make that material less useful. It makes the difference between code and judgment a lot easier to see. A giant prompt full of confident bullshit does not fix this either. Somebody still has to know what belongs in the context.
Language familiarity matters less than it used to
Section titled “Language familiarity matters less than it used to”I have noticed the same thing happening with programming languages. I used to weigh familiarity pretty heavily when deciding what to build something in. That still matters, but less than it did.
If an ingress service or long-held connection would be a better fit for Elixir, Go, Rust, or something else, an agent can absorb a lot of the syntax, library lookup, and unfamiliar project-structure tax. That makes “which one can I personally write fastest?” a less important constraint.
It does not make the languages interchangeable. The runtime, concurrency model, operational complexity, and failure modes still matter. If anything, removing some of the implementation friction puts more weight on choosing the right tradeoffs in the first place.
That feels like a broader version of the same change. The mechanical cost of trying a different implementation drops, but the cost of making a bad system-level decision does not.
Working code can outrun your understanding
Section titled “Working code can outrun your understanding”Agents can make locally reasonable decisions very quickly. You add projects, so the agent gives them an account_id. Later it adds reports. Later billing needs an account. Then background jobs need tenant context. Then users can belong to multiple accounts.
Every diff can look fine while the application slowly accumulates different answers to the same architectural question. Nothing has to be obviously broken. The tests can pass, the controller can be small, and the service object can have a perfectly respectable name while the code is still making the system harder to reason about.
This is not really a beginner-only problem. Experience helps because you have seen more bad outcomes before. There is a lot of scar tissue inside “I would not put that there.”
A newer developer has another problem: an agent can let them build much farther than they understand. I do not think the answer is forcing somebody through an architecture quiz before the agent is allowed to touch a file. Nobody is going to work that way, and I would not want to either.
People are going to use the leverage. The education around it has to care about more than teaching the part the agent can already execute.
What I actually want from an expert now
Section titled “What I actually want from an expert now”I do not need an expert because they can type the code faster than the model. I want the stuff that is annoying to rediscover.
Why is this boundary here? What are the reasonable alternatives? Which shortcut looks harmless until production traffic arrives? What should be authoritative, and what can safely happen twice? Which part did you try three years ago and would never build that way again? What should the tests prove? Which ugly-looking bit should I not let the agent “clean up” because it is protecting behavior that is easy to miss?
That is the material I want to read. It can absolutely live in a book or an article, and I still want the human explanation first because I need enough understanding to review what gets built.
I just also want the useful part of that expertise to make it into the implementation.
The human and the agent do not need the same version
Section titled “The human and the agent do not need the same version”For me, the human side should explain the mental model, tradeoffs, failure modes, and enough of the implementation that I can tell whether the result makes sense.
The agent needs something more direct: inspect these parts of the repository first, preserve these boundaries, do not make this provider authoritative for that state, these operations have to be idempotent, and these are the cases the tests need to cover. If the existing application conflicts with the recommendation, stop and point it out instead of quietly inventing a third approach.
That is much more useful to me than adding a chatbot next to a course or putting a “Prompts” chapter at the end.
It is also how I backed into adding Agent Companions to Webhooks in Rails and Billing in Rails, and why Rails Baseline has so much context aimed at coding agents. I did not start by deciding those products needed “AI features.” I kept getting to the end of useful technical material and being annoyed that the next instruction was basically, “okay, now go apply all of that yourself.”
The agent is already sitting in the application. Giving it good context is the part that was missing.
Good input is not a magic trick
Section titled “Good input is not a magic trick”One response to the first article described average input producing average output from an LLM. That is not a hard rule, but I like the framing.
If I tell an agent “add billing,” the model has to fill in a lot of blanks. If I give it material from somebody who has already thought through account ownership, provider boundaries, failed payments, retries, entitlement state, reconciliation, and the tests that should prove those things, the same model starts from a much better place.
That does not mean the expert has to predict my codebase. The agent can inspect that. The expert needs to know which questions matter when the clean example collides with a real application.
That is a different job from writing 40 sequential steps that assume everybody started from the same rails new.
I do not need the book to turn into an AI product
Section titled “I do not need the book to turn into an AI product”I would still buy a good technical book, and I would also pay for good agent context if it saves me from rediscovering mistakes somebody else already made. Those are not competing products in my head.
Sometimes I want to read the entire thing because the reading itself is useful. Sometimes I want an agent to search the PDF, compare one section with my code, or tell me whether the repository already satisfies the recommendation. The book can stay a book. The article can stay an article. The useful part should not have to disappear when I close the tab.
If the material is intended to help with implementation, I also think it has to be maintained differently than old sample code often was. Dependencies change, framework conventions change, APIs change, and models get better at different things.
Maybe the update is a changed recipe or better verification. Maybe it is new agent context. Maybe it is just an explicit note saying, “yeah, I would not do this part the same way anymore.”
I would rather have that than pretend an old sample application stays canonical because the video still plays.
So, now what?
Section titled “So, now what?”I do not think there is one replacement for the programming tutorial. Short tutorials are still useful. Documentation is still useful. Books are still useful. Long explanations from people who know a subject much better than I do are still useful.
What changed is where I want the workflow to end.
The old finish line was often that I understood the example well enough to reproduce it. I want to understand the decisions well enough to review them, then have the useful parts of the expert’s experience available while an agent looks at the application I actually have, adapts the work, and verifies that the important behavior survived.
Code generation got cheap faster than engineering judgment did. I am still very willing to learn from, and pay for, the judgment. I just want it to make it all the way into the software.