Note from Adam: this article was originally written in 2025 There’s been a lot of conversation about using AI in software development. We all know AI isn’t (yet) a total, or even reliable, solution for many problems. But used in the right context, it’s a genuine game changer. When it comes to software development — and a lot of other things in life — there are three sayings I keep coming back to: When it comes to AI-assisted coding (I’m trying not to use the “v” word) in 2025, we’re still in the crawling phase of the growth cycle. It leaves a lot to be desired, largely for the same reason AI often struggles: it’s trained heavily on data lying around the internet, and we all know how reliable that can be. But is there a place for AI-assisted coding today? Absolutely — when it’s used correctly. In this article, I’ll show how to combine AI with other tools to build a turbo-charged development environment that dramatically cuts the time it takes to build applications, while delivering better, more secure code. Vibe coding is extremely powerful, but it can violate both of the truths I mentioned above. It can tempt veteran engineers into scrapping their best practices and diving straight into code. Worse, on larger projects, vibe coding really struggles to keep the whole project in context. In other words, you start coding too soon and end up with a false sense of security about your project’s quality. One of the classic requests we get goes something like this: A client comes to us with an application that needs serious updating. Say it’s a two-tier app (front end and back end) built on languages X and Y. We’re asked to: The usual response is an estimate measured in weeks or months. But what if we could do all of this in much less time — over lunch? Keep reading to find out. Remember the “right tool for the right job” saying? Here it is in action: While AI is the wrong tool for plenty of jobs, it excels at reporting and planning. So when it comes to the software delivery cycle, why not put it to work on exactly that? In the diagram above, we start with an existing application. (If you’re not starting from an existing app, the process is the same — you just start with a hand-written Application Spec.) It is, but that’s not what we’re doing here. In this scenario, we let AI do all of the coding. So why does that work here but not with “vibe coding” (cringe)? When you’re vibe coding, AI only has a slice of the application in view when it makes a change for you. That change might be perfectly valid in a narrow scope, but disastrous in a larger scope it can’t currently see. When AI is armed with the full scope of the application, it’s a completely different world. It doesn’t have to work around pesky humans mid-stream — it’s free to make its own plan and execute it. It knows the entire context because it made the plan. Will it still make mistakes? Absolutely. But they’ll be far less frequent, and far more easily caught by the guardrails we put in place. I built this whole process first with a few small Python applications, but eventually it was time to try it on a production application. One of our clients was interested in modernizing an app with: To put the concept to a real test, I used that codebase — and had AI rebuild it with Python on the front end and Node/TypeScript on the back end. Reminder: if you’re not starting from an existing application, you can just write the Application Spec by hand. Why spend a day digging through code when AI can document the application for you? This is a task AI is genuinely great at. As I noted earlier, the key is giving it the right kind of instructions. As I repeated this process, I found better ways to instruct AI — and, fittingly, AI helped with that too: after finishing a new app, I’d ask it to summarize what went right and what went wrong, then use that summary to update the instructions for next time. While I’m generally bullish on AI, running this process over and over showed me just how fickle it can be about following directions. I put a lot of care into the detail in the specs for the new app. Here’s an exchange I had with GitHub Copilot: This felt exactly like an exchange with one of my teenagers. We’d just written a detailed spec in another session, and I asked AI to review it and ask any questions before starting. It proceeded to ask questions that were clearly answered in the spec. I called it out, and after that, we were good: At this point, you just tell AI to “go,” and it does its thing: This kept going for a while, but the entire process only took about 30 seconds. Now it’s just showing off. I should back up for a second and talk about code quality analysis — something every dev shop should have in place, but rarely does. Tools like SonarQube act as the center of the software development world. I won’t go too deep into the weeds, but the gist is this: a company can define rules and scans that guarantee code created in their environment meets every requirement, including security. This can all be set up so failing certain scans blocks deployment outright. The advantage of tools like this is that they’re centrally defined and controlled — change a scanning profile once in SonarQube, and every connected app picks it up going forward, with no code changes needed. SonarQube also does a great job reporting on tech debt, open issues, and more. I mentioned there are things dev environments should be doing but rarely do — automated testing is right up there. In my instructions for the Application Spec, I asked AI to write test cases that run automatically on every commit. Tests should cover any action or process that does something — for example, every API endpoint should have a test confirming it returns the expected result. Here’s what that looks like: Beyond the obvious benefit, automated testing unlocks something else: it’s the safety net that lets us use vibe coding for smaller changes going forward. AI has been known to make a change in one context that breaks something unrelated in another. Without a careful dev or BA in the loop, that can slip straight into production. Automated testing is a great way to catch that before it does. At this point, AI has built a brand-new application with front-end and back-end services coded to spec, following the company’s coding standards the whole way. But does it actually work? In this attempt, everything fired up and worked correctly on the first try. I can assure you that wasn’t always the case — so why was it perfect this time? As I mentioned, I fed the lessons from each earlier attempt back into the process. I intentionally didn’t give instructions on the UI, because I wanted to see what AI would come up with on its own. I asked for something clean and responsive, and it delivered. I could just as easily have handed it wireframes or reference images, and it would have used those instead. You might be wondering where the data came from. I had AI build the endpoints the application needed, but set it to a “dev mode” where they returned static values. That’s a useful practice for automated testing too — you generally don’t want your tests running against production systems. Part of why I ran this on a real application was to prove the process works regardless of the technology involved. I’ve done a little work with .NET, but not enough to easily follow some of the middleware logic in the original app — and in fact, I didn’t do any of the analysis myself. Which brings me to the key point: This isn’t just reproducible — it can be done almost entirely by a business analyst. Why? Because every prompt and instruction AI used to build the new application is written in plain English. If you want to tweak or customize something, a BA just needs to update the instructions. Okay, it was a flashy title. Could the whole process be done in under an hour? Yes, absolutely — I could probably get through it in well under that, given a clean path. The good news is it doesn’t need to happen in an hour. Also, the ROI on a process like this is almost immediate — and as it gets refined further within a client’s environment and efficiency keeps climbing (while coding issues keep dropping), that ROI only grows over time.Modernize an App on Your Lunch Break?!
App Modernization in the New World
The Use Case
The Approach

Wait — Didn’t You Just Say AI-Assisted Coding Is Dangerous?
Talk Is Cheap — Let’s See This in Action
Step 1: Document the Current Application to Create the Application Spec

Step 2: Review the Specs with AI

AI: The Teenager Who Won’t Listen

Step 3: Creating the Application



Step 4: Code Scanning


Step 4 (Again): Automated Testing

Step 5: The Finished Application


Marketing Aside, Is This Reproducible?
Is This Reproducible Over Lunch?






