AI Pair Programming Is Powerful — But Only If You Move Fast
What building Thinkery taught me about the point of AI
Introduction
In my last article, I argued that picking the right stack can make all the difference when AI is writing your code. I think that languages like Elm fit in the core of your stack since they enforce correctness. Since then, I have put out the first cut of Thinkery, a writing tool that gets the AI right, using Elm at the core of my stack. (Try Thinkery for free at https://thinkery.world) It is a non-trivial app, and it’s given me ample opportunity to put my theory to the test. And, here’s what I learned.
A strict, compiled language is great!
Web apps tend to be written in React, using Javascript or Typescript. You can bolt on type safety and immutability, but these are optional. (Besides, there is no cure for useEffect.) However, Elm comes with type safety and immutability built in. The compiler will just not let you write unsafe code. Here are some of the ways it keeps you safe:
1. There is no null.
2. All variables are strongly typed.
3. If you forget to handle all possible values of an enum in the Elm equivalent of Javascript’s switch statement, your code will not compile. Elm forces you to address all possibilities.
4. You need to explicitly convert external data into strong types using Decoders, so that unexpected types coming from sources you probably have no control, will not crash your app.
The Elm compiler nudges you towards good code with its helpful and human readable error messages. They’ll guide you and your AI Pair Programmer towards good, error free code. Handle your errors, and your app will never have a runtime exception.
Velocity is the way
You’ll probably face two kinds of issues when building a software based business:
You are not solving the user’s problem: Business is about solving your users’ problems. Your fascination with your software is not reason enough for them to give you money. As programmers, we are prone to becoming obsessed with something we’ve made. It then becomes a solution looking for a problem. We need to fight this urge because you can waste years trying to find users. When you’ve hit the right product-market fit, there’ll be nothing subtle about it — it’ll feel like you’ve stepped on a landmine.
You are not solving the user’s problem in a realistic way: This is when you are addressing the user’s problem, but you are making it really hard for them to use the software. Take, for instance, this app meant to help doctors that had about 48 fields, including ones about cancer and hereditary diseases, which all needed to be filled in even if the patient only had a cold. It increased average consultation times from a few hundred seconds, to nearly ~23 minutes!
Both these sorts of issues are solved by putting your software in the hands of your users, listening to them, making changes accordingly, and repeating this cycle all over again. According to Andrew Ng (the co-founder of Google Brain and more relevantly, the person that runs AI Fund, an incubator that builds AI companies) the faster you can go through these cycles, the greater your chances of success. If you look closely, this was always the case — the need to iterate hasn’t arisen just because AI came along. However, with AI, you can iterate rapidly, making it highly likely that you can quickly hone in on what the user needs.
Embrace AI
If velocity is the goal of modern day software development, then you really need to ask yourself whether you can write software faster than AI can. Trying to out-code AI is like charging tanks with swords. You can try, but you won’t win.
Yes, there are times when AI gets stuck in a loop, and you should get in there and fix the problem. But, step back again, and let the AI Pair Programmer do its thing. Recognize that your task has changed from writing code to managing your software’s development. If you aren’t convinced, consider this: AI can just as easily write code in WASM, Assembly, Byte Code or even Machine Code directly. What is written will effectively be opaque to you. What then? Step back and learn to direct AI’s enormous power.
There’s no magic bullet
Until the day that Cursor, Windsurf, Claude Code, Gemini CLI, OpenAI Codex, GitHub Copilot, Zed, Cline and the others can individually get everything right on the first go, know that you have an arsenal of tools and methods at your disposal. Learn to use them well.
Planning: I routinely plan features with ChatGPT. When I wanted to build an editor into Thinkery, and had been toying around with the idea of building a markdown parser by myself, ChatGPT set me straight. Told me that this could be more painful than necessary, and that there were off the shelf components that I could use. It recommended different components based on how much time I wanted to spend experimenting. I made up my mind after I saw a couple of the websites, and implemented an industrial strength editor into Thinkery.
Scaffolding: I have scaffolded projects using Claude Code (using Sonnet 4). When using AI, you have to be quite explicit with what tools you want to use or they default to the popular ones. I prefer bun, for instance, so I routinely have the tools trying to use npm and having to interrupt and steer them, until I put the comments into the code, telling the AI what tools I use. Then again, why not just use the popular ones? The task of how to achieve something is no longer my concern — it’s the AI’s. So, in a new project, I stuck with npm.
Feature building: I use Gemini Code Assist (using Gemini 2.5 Pro), to build features. (A great alternative in-editor alternative is Cline, but I haven’t found myself using it as much now that Gemini Code Assist is working again.) Once Gemini finishes the first cut, I fix any errors that pop up by right-clicking them in Visual Studio Code, and clicking “Fix”, which uses Github Copilot (using GPT5-mini). That tends to be much faster than having Gemini Code Assist take another gander at it.
Bulk edits: If there is code that needs to be edited at multiple places, and it’s not something mechanical that can be fixed by right-clicking and clicking “Rename symbol”, for instance, I switch to Windsurf (using SWE-1) and make the changes there. Windsurf is very good at helping you find and make logically similar changes, and I just Tab-Tab my way through. So, why not just use Windsurf all the time? I find it too aggressive; it’s just a matter of taste.
Dynamic landscape
When I started building Thinkery, Gemini Code Assist was abysmal. I would ask it to do something, and it would spend so much time thinking, and at the end, it would output nothing. Not bad code, an unfinished response, or platitudes — just nothing. It was unusable. I switched to Gemini CLI, and had much better luck with that. After a hiatus of a month or two, I tried Gemini Code Assist again, and things had changed drastically. It works brilliantly now — keeping you updated about what it is thinking, and then, when it is ready, it makes the changes to your code, across files, tells you what the problem was and how it fixed it. And the code usually works perfectly. I seem to have stopped using Gemini CLI altogether, now.
Windsurf too, was something I used to use a lot. It is great. Aggressively helpful, but great. Even when it was my main driver, I used to have Visual Studio Code running as well and would switch to that if I wanted some control. I used Claude Code to scaffold a project once, and then never touched it after that. I do use Sonnet 3.5 lots though, through in-editor plugins like Cline or Continue. Cline was my go-to before Gemini Code Assist became usable again. Switched to Continue and found it to be more efficient than Cline, but then, lately it has been having so much trouble applying its changes, I’m scared to click the “Apply changes” button.
The bigger point is this: The landscape is changing on a daily basis. Our task is to know what tools are out there, know when best to use each, learn what works for us, and keep an eye on what part of our workflow needs fixing. Our allegiance at all times, is to the software we are building, not to the tool.
User experience is the goal
Stepping on the accelerator is fine and dandy, but where are you headed? Better user experience. There is very little software that doesn’t require interaction with users. In fact, I can’t think of any. Even the bits that live at the hearts of operating systems required to be understood by someone who had to interact with it. It’s incredibly important that you get the user experience right. One can argue that the point of choosing a language, a framework, a platform, a device, or any other choice we make when building software, has to be geared towards providing a better user experience. User Experience is difficult to get right but is extremely obvious to the user. It can make or break your software. But don’t pay attention to it only out of fear — getting it right can also give you a resounding, entrenched advantage over your competition.
Some other tips
Here are some other things I do to help guide the AI Pair Programmer along:
Instructions for your AI: Many of the tools allow you to write your instructions for your AI into a tool specific document, like claude.md or gemini.md. You may want to try this. But, don’t get too enthusiastic and write a tome — it gets included in every prompt and putting in too much could degrade your performance.
Self-documenting code: Name your functions and variables with meaningful names. AI will understand it better.
Models behave differently: Here’s a reminder that the same LLM used through different tools can yield different results. Using Gemini 2.5 Pro, for instance, through Gemini Code Assist versus using it through Cline, can yield different results. Try different combinations to see the best model for a tool.
Conclusion
The arc of technology leans towards invisibility. It’s the voice based assistant that you pocket away without a care because you know what you asked for will be done. It’s the self-driving taxi that is so reliable that you doze away in the backseat. It’s the device you approach and know how to use instantly. Good technology disappears into the background, allowing us to be more human. The immense power of AI allows us builders to push the envelope on the user experience. Push hard.
This article was written in Thinkery! Try it for yourself at https://thinkery.world!


