Six real-world AI cases in Drupal this week

This week I've had six different situations working with AI where the tool saved me hours, but also tried to slip in solutions that weren't the right ones. I wanted to walk through them because the conversation usually focuses on what AI does well and not much on what it costs to review what it hands back, and in my day-to-day those two sides go together almost without exception.

For those who don't know me, I'm a freelancer. I do quite a bit of subcontracting for agencies, and for a while now I've also been taking on the occasional end client more sporadically. The cases I'm covering this week come from a mix of all three fronts: my own personal projects, end-client projects, and projects that get passed to me from one of the agencies I collaborate with.

Before getting into the cases, there's something worth keeping in mind that often gets lost. Generative AI works by predicting probable text, not correct text. It generates code that statistically makes sense based on the patterns it's seen, but that doesn't mean it's the best solution for your case or that it's free of errors. It often invents functions, applies patterns that don't fit the project's architecture, or repeats bad practices it's picked up from somewhere. If you don't review with judgment, what you gain in speed you lose in technical debt down the line.

I do all of this from my public DDEV setup with Claude Code and OpenCode, which I've published as ddev-ai-workspace and have written about in previous posts. It's a repo of mine where I've been collecting how I work on my own projects and my clients' projects with what I consider best practices. If you work with Drupal and use DDEV, I recommend giving it a look and trying it out. Besides the repo, all you need is a subscription to the models you want to use or their API keys.

The patch that wasn't needed

One of the patterns I run into more often than I'd like is that you describe a Drupal problem to the AI and the solution it proposes is to generate a patch for a contrib module, or even worse, for core. It happened twice this week.

In the first case, the real problem wasn't in the contrib module but in an incompatibility with custom code we had in the project. The right fix was to adapt the custom code, not patch the contrib. In the second, I ran a deep research from Claude to check whether the community already had a patch fixing the issue, and it turned out there was one. In both cases the AI diagnosed the bug correctly, analyzed it well, and understood why it was happening, but the solution it proposed was wrong.

Without the judgment to assess the proposal, I would've ended up keeping custom patches on contrib modules, which is textbook bad practice and a guaranteed headache the next time you need to update.

Refactoring templates without losing your mind

In another project we're migrating the frontend to Tailwind CSS, and this week I refactored a decent chunk of templates, preprocess hooks, and JavaScript and CSS files from an old theme to a new one. I have some custom skills that read the HTML comments Drupal renders on the page and from there figure out which template needs to be modified, which one needs to be created, and when a hook_theme_suggestions is needed to introduce a new template. It works pretty well and saves me a lot of hours.

The thing is, if you don't review the code carefully, you run into a few problems. The most common one is inline CSS and JavaScript stuffed directly into the .twig file when the right approach in Drupal is to have components with separate files. Another is generating duplicate templates that could easily be a single generic template with a small variation. And the third, which is the most insidious, is replicating bad patterns that already existed in the old code. If the base it's looking at for inspiration has bad practices, it copies them enthusiastically and the snowball keeps growing.

I have all of this specified in my skills, but even so the AI sometimes fails and ignores the prompts it has configured, so skimming the diff before accepting anything is mandatory. When I spot something wrong, I just say "not like that, do it this way" and it corrects itself, but someone without experience writing Drupal templates wouldn't catch the problem and would end up with a template architecture that's painful in six months. Another thing I've found is that when I spot a bad pattern, I ask it to search the rest of the codebase for the same pattern and fix all of them at once, to move business logic out of the twigs and into preprocess hooks where it belongs.

Even so, what I got out the door that same afternoon would have easily been a week's worth of manual work.

From admin interface to Drush command without rewriting the module

In another project we have a custom module that runs incremental migrations from a Drupal 7 site. Besides running the migrations, it offered an option in the admin interface to clean up nodes and entities that no longer existed in the source system, which we need because the destination site is still in development and we want it to stay as in sync as possible with the real content. The client asked us to convert that part into a Drush command so it could be automated via cron alongside the incremental migration.

By hand, refactoring the code to extract the logic from the admin screen, build a well-structured Drush command with its parameters, and get it tested would've been a solid chunk of work. Handing the AI the context and asking it to reorganize the existing code so that the same flow works from both admin and the console cut that down to a fraction of the time. The boring part of wiring up the command parameters, validating inputs, and moving code between classes without duplicating it was done by the agent, and I was left with the part of reviewing the final architecture and confirming that both paths run exactly the same logic.

Half an hour for a bug that had been dragging on for hours

The clearest case of the week was with someone from an agency who'd spent hours trying to figure out why the pagination on a taxonomy view was disappearing in what looked like a random way. They explained it to me, I replicated it locally, confirmed it wasn't a JavaScript issue, and handed the context to my AI: here's the problem, here's what I've already ruled out, find the cause. While the AI investigated, I carried on with my other tasks in parallel.

When it finished the analysis, it had correctly identified that the problem came from an EVA, a view used as a field, inside the view mode of a content type. The EVA's pagination and the taxonomy page's pagination were conflicting because they shared the same paginator identifier. Up to that point, perfect diagnosis. But the solution it proposed was wrong. It told me to remove that field from a specific content type, but in that content type the field wasn't even enabled. Since the taxonomy view is generic and renders multiple content types, the AI had got confused about which content type the real problem was in.

When I reviewed it I told it that wasn't the content type and set it to investigate again. When it came back it said "ah, right, not that one, it's this other one", and from there we got to the right conclusion. Which wasn't to change the paginator ID either, but that the view mode was misconfigured. In the twig templates we only render two fields and the title, so the EVA and the rest of the fields enabled on that view mode shouldn't have been. Disabling them on the view mode fixed the bug and, as a bonus, improved performance because when rendering that view mode we no longer load a bunch of fields into memory that never end up being displayed.

From hours wasted to half an hour well spent. And it's not that the AI got everything right, it's that it sped up the slow part of the diagnosis while I handled the judgment calls.

Updates and PHPCS on loop, in the background

For my own personal projects in maintenance mode I've set up something different. I ask the AI to update Drupal and the contrib modules, check that everything still works after the update, and generate fixes for the problems detected by my own contrib module drupal/audit, which I have configured to spot bad practices in twig templates, performance issues in custom code, configurations that shouldn't be the way they are, and the typical PHPCS and PHPStan warnings.

Since the module comes with its own Drush command, the AI knows how to run it, interpret the results by category, and apply the appropriate fixes for each case, so the loop closes end to end without me having to manually verify what needs fixing. Most of those warnings aren't critical, but they're exactly the kind of thing you keep postponing forever because it's not a priority.

I leave it running with a RALPH loop in the background and it works through iterations on its own. When I come back to check, the fixes are done. I just have to do a quick review to confirm what it's done makes sense, run the tests to confirm nothing's broken, and push to production. What used to be a boring task I'd park for weeks now gets solved with a few minutes of supervision, and on top of that it stays in a recurring loop instead of being a one-off sprint I do when I remember it exists.

Applying migration changes in the background

Going back to the migrations project, I've had for some time a couple of automated tasks in my workspace specifically for modifying and generating Migrate module YAML files, which I've already talked about in a DrupalCamp talk and in other posts on the blog. This week the client asked us for several changes to the migration after reviewing the first results, and the way to apply them was literally to tell the AI "here are the files, here are the changes, apply them". The AI modifies the YAML, runs the migration, checks the results are correct, and leaves everything ready for me to review and commit.

What used to take several minutes or a couple of hours of local testing now gets done unattended in the background while I work on other things. I just step in to check that the applied change makes sense, that the results match what the client asked for, and from there I move on.

What I take away from this week

Used well, AI saves a lot of time and unlocks things that weren't worth doing before. While I'm in a meeting or handling a non-coding task, I can leave the agent analyzing a bug or applying automated fixes in the background, and that multiplies what gets done in a week. The template refactor that took me a few hours this afternoon would've easily been a week's work two years ago. The pagination bug that had been keeping the agency busy for hours was solved in half an hour.

What doesn't change is that everything AI delivers needs to be reviewed. And not because "it sometimes gets it wrong", but because more often than I'd like it hands you something that works but is poorly designed. If you reload the page in the browser everything looks fine, but if you open the code you see CSS where it shouldn't be, duplicate templates that shouldn't exist, business logic in twig instead of in a preprocess hook, or configurations that load entire entities into memory just to render two fields. It works, but maintainability suffers and technical debt piles up without the client seeing it.

And then there's the snowball effect. If the existing code already had bad practices, the AI happily replicates them in every new part it generates, so any codebase with prior problems amplifies those problems at agentic speed. That's why reviewing isn't optional or a "recommended best practice", it's what separates the AI actually helping you from just helping you generate more debt faster.

Something I've been learning is that the more you work with AI, the more you need some systematic way to measure project quality, because if you just eyeball it anything slips through. That's why I use the audit module on every project, configured with the checks that make sense for that client, and that's why I also built DruScan, a SaaS dashboard that connects with the module and keeps history of the scores per environment: development, staging, and production. That gives me a picture of how the code's health evolves over time, which becomes especially useful when there are other people touching the project besides me, which happens fairly often in my case because I collaborate with multiple agencies on projects of different sizes. The module is free and already documented in other posts on this blog, and DruScan has a free tier in case you're interested in trying it. If you do, I'd appreciate any feedback.

When it comes to the financial side, the math works out. Even though tokens cost money, if someone using AI well does in an afternoon what used to take a week, the savings in hours compared to what you spend on tokens is huge. And for automated tasks like updates or PHPCS fixes, the real alternative isn't doing it more cheaply by hand, it's never doing it at all because it never becomes a priority. Going from parking that debt for months to having it under control with a few minutes of supervision per iteration is one of the things that most shows up in the final quality of the project.

Need a Drupal Expert?

Senior Drupal developer, freelance, specialized in what's hardest: migrations, multilingual sites, SaaS platforms and Stripe integration. I leverage AI to cut delivery times and costs, with expert review on every line of code.

No agency, no middlemen. Direct contact with the one who does the work.