AI · October 18, 2026 · 8 min read

What AI Actually Changes About Writing Software

Code generation is the visible part. The larger shift is where engineering effort goes once typing stops being the bottleneck.

DA

Dimas Adit Thalia Putra

Fullstack Developer

What AI Actually Changes About Writing Software

After a year of using AI assistants daily on client projects, my conclusion is less dramatic than either camp suggests. The tools do not replace engineering judgement, and they are not a toy either. They change the cost of certain activities, and that moves where the real work sits.

What got cheap

Anything that is well specified and well represented in public code is now close to free:

  • CRUD endpoints, form validation and DTO mappings
  • Test scaffolding and fixtures
  • Boilerplate for a framework you know conceptually but not syntactically (a Laravel policy, a Prisma migration, a Flutter form)
  • First drafts of regexes, SQL queries and shell one-liners

This is real leverage. A feature that used to need an afternoon of plumbing can reach a reviewable state in twenty minutes.

What did not get cheap

Three things stayed expensive, and in practice became the bottleneck:

  • Deciding what to build. A model will happily implement an ambiguous ticket. It will not tell you the ticket is wrong.
  • Reviewing. Reading code you did not write is slower than writing it, and generated code arrives in volume.
  • Owning the system. Someone still has to understand why the payroll job runs at 02:00 and what breaks if it does not.

Review becomes the main skill

When generation is cheap, the limiting factor is how fast you can verify. I now treat generated code the way I treat a pull request from a new contractor: plausible, often correct, and occasionally wrong in ways that look right.

A review checklist that has caught real problems for me:

  • Does it handle the empty, null and duplicate cases, not only the happy path?
  • Are authorization checks present on every new route, not just the first one?
  • Did it invent an API? Hallucinated method names compile in dynamic languages and fail at runtime.
  • Does it match the conventions already in the repo, or did it import its own?
Fast generation without fast verification is just a faster way to accumulate debt.

Tests as the contract

The most effective habit I picked up is writing the test, or at least the test names, before asking for the implementation. The test is a precise specification the model cannot misread, and it gives you an objective way to accept or reject the output.

describe("calculatePayroll", () => {
  it("prorates salary for mid-month joiners", () => {});
  it("caps overtime at the legal weekly limit", () => {});
  it("returns zero tax below the non-taxable income threshold", () => {});
});

With that in place, a prompt like "make these pass without changing the signatures" produces much better results than a paragraph of prose.

Where it still fails

  • Large, implicit context. Business rules that live in people's heads or in a ten-year-old module are invisible to the model.
  • Performance and concurrency. Generated code is usually correct on one request and quietly wrong under load.
  • Security boundaries. It will reproduce the common insecure pattern if that pattern is common.

What I would tell a junior developer

Learn to read code faster than you write it. Learn the fundamentals (HTTP, SQL, the event loop, transactions) well enough to smell a wrong answer. The developers who benefit most from these tools are the ones who could have written the code themselves and are using the tool to skip the typing.

The job is shifting from producing code to specifying, verifying and operating it. That is still software engineering. It just rewards a different part of the skill set.

  • #AI
  • #Software Engineering
  • #Productivity

Keep reading

Portfolio©2026

DIMAS

Loading the experience

000