Rucord - the vibe coded iOS app

Rucord - the vibe coded iOS app

I've had a bit of fun recently trying to Vibe Code - in the original sense of the word - some small apps. And it's mostly worked well, at the very small scale

There’s a new kind of coding I call “vibe coding”, where you fully give in to the vibes, embrace exponentials, and forget that the code even exists. - Andrej Karpathy

I've done a couple of small cron jobs - one which monitors an RSS feed for changes and hits the Overcast webhook, and another which monitors the Island Direct website for specific changes, and sends me a push via Home Assistant.

Neither of them are huge - maybe 50-100 lines of typescript code - but it was fun to do, and they run constantly on my NUC, just doing their job.

But I wanted to do something a bit bigger, to see how far I can push this in a greenfield situation.

🤖
While all of Rucord was written by an LLM, none of this post was. I enjoy writing, so why let the robots do the fun part?

Enter RUC Buddy Rucord. (yes the original name was shit, thanks Jono for the better one)

Rucord is a small iOS app for recording your RUC - Road User Charges - in New Zealand. This was something only diesel vehicle users had to do, and now EV and PHEV have to do, with the government indicating that all users might have to do it in the near-ish future (it's built into the petrol cost right now. Lets ignore that if they take 70c/L of tax away, the price isn't going to stay down for long....)

For me, the hardest part of trying to learn something like a new tool or language is often coming up with a project of the correct scope - not too big that you are thinking about the problem more than the tool your evaluating, but big enough that you can stretch your legs with the new tool.

This seemed like a suitable size, and in a technology that I have enough knowledge of to not have to think too much about the terms of art and mechanisms.

Plus, day to day, I don't get to write much code on the Tend product (sadly). I've found that being in the critical path is a very very bad idea(tm), assuming we want to actually ship something.

So, the scope and tools

  • An iOS app, using SwiftUI, to record your RUCs, allowing for multiple cars, prediction of when the RUC was going to expire
  • Using anything I had available: Amp, Claude and Claude Code, ChatGPT, Gemini, Stitch (Codex wasn't out when I started)
  • While I can look at the code, I'm not allowed to edit MUCH of it. I can do basic things which would be (in my opinion) either too basic, or too complex, to ask the LLM to do. Better yet, both. An example of that would be making a new Xcode project (file -> new, give it a name), or changing the developer ID (urgh XML config files, but a dropdown in Xcode).

Amp was my main tool here, and I really enjoy using it. I mostly use it on the command line, and this was done over about 9 threads and maybe 4 weeks of wall time. The actual time spent "building" the app was maybe 3 days.

I started out doing one thread per feature, or per session. Initially, I gave it some basic instructions: (yes, the prompt has spelling errors)

I have a basic, empty ios swiftUI app in the current folder. The app is a new, basic app to record the RUC (Road User Charges) for a car. You should be able to add 1 or more cars (by number plate - eg ABC123), and be able to track the current odometer value for that car over time. I also want ot be able to project when the RUC will expire - when the car hits a specific mileage. The front screen should show the list of cars, the last recorded mileage, and a projection of how long it is before the user needs to buy more mileage

And it went off to do it. I think I got Claude to write a basic AGENTS.md file, which I edited a bit. I wanted to allow it to run the app in the simulator, but it never quite got there (it was running the right commands, but Apples tools didn't play ball), so I just kept the project open, and hit build/run.

I also called out that it had access to git, and the gh command line apps. This was handy for getting Amp to commit and push at various points.

Following up with a rename, then some more UI work to make the cars editable, and finally I used Stitch to do a basic design and told Amp to go implement it, only providing it with a PNG of the output.

The last one worked fairly well, tho I could never get it to do the side padding/margin properly. We did work it out in the end.

About now I needed an icon, so I got ChatGPT to make one for me.

Once the app was up and working fairly well, I changed tack a bit: I wrote a TODO.md and started telling Amp to do the things on the list. I wanted it to do one, wait for me to try it out in the simulator, suggest changes, and when I said it was ok, then commit, push and move to the next one

ok, I've added some things into TODO.md. Want to tackle the first few formed ones. Make sure the app compiles after each one, and wait for me to check it. Once I'm happy with the change, commit it and push it to github, then do the next one

This worked... a bit too well. It did that for the first one, then it went off and did everything else in the list. After 2 or so, I stopped it and reworked the prompt

The original instructions where not clear enough I guess
* do thru the TODOs which are formed, doing the one at a time
* for each one, do the change, make sure it builds, then deploy it to the simulator, and STOP so I can check it
* Once I tell you that I'm happy with the change, mark the TODO off, commit that change to git and push to github
* Now do the next one - making sure you continue to stop after making the change and before comitting

This worked a lot better, and it largely did what I told it to do. I kept doing that for most of the rest of the development. I also used it to do some research on In App Purchases, which were not working right (I didn't have them setup and ready for review in Appstore Connect), and back to the TODO loop.


At this point, I had a pretty usable, reliable iOS app, so I thought I might as well put it in the store. Now that part was a total PITA. I get that Apple are dealing with "the world", and it's a messy place, but their process for signing up and getting to the point of submitting an app is arcane, poorly documented and confusing.

And keep in mind that I did this for my apps - and ANZ/Pushpay/Tend - from 2010 or so, and it's far from my first rodeo. At least provisioning and code signing has gotten a lot better.

I'm not sure the app needs to do anything more, so I'll leave it up at least until I can't be bothered to pay the $150/year to Apple. But the source is available on Github, and I even got Amp and Claude to write a simple one-pager for it.

Rucord — Simple NZ Road User Charges tracking
Rucord helps New Zealand drivers stay on top of Road User Charges (RUC). Track odometer readings for one or more vehicles, see exactly how many kilometres remain on your current RUC block, and get timely reminders before you run out. Who it’s for * NZ drivers of diesel vehicles, light
GitHub - nicwise/rucord: A management tool for NZ RUC charges
A management tool for NZ RUC charges. Contribute to nicwise/rucord development by creating an account on GitHub.

What did I learn

A common complaint with people using LLMs is "but you don't learn anything". I disagree, to some extent. It depends on your goal.

My goal here was to learn how I can exploit LLM-based development tools and how to communicate with these new tools to make the most use out of them. The goal was not learning SwiftUI.

I think it's worked pretty well. I have a much better idea of how I can drive Amp, Claude Code etc, and when its time to step in and do changes myself. Sometimes trying to prompt your way to victory is absolutely the WRONG way to do it.

Having some more engineering infrastructure around this would have made it flow a lot better. For example, if this was on our app at Tend, we have CI/CD, integration tests, and automatic deploys to TestFlight and Google Play. I could build those for Rucord, but it's just me, so I'm not sure it's worth it.

I found once I had some momentum, the TODO.md method worked really well. That shouldn't really surprise, tho - an agentic coding tool is a LLM in a tool loop, so why not wrap that loop in a loop. Loops all the way down.

One thing I found - and I've found this at work too - is that it is amazing for those with fractured time. The mental load of task switching is almost gone, I can just get on with making the thing, rather than having to page in whatever I was doing last time. I found I could just drop in, do a bit for 5-30 mins, commit it, do something else, come back (maybe a week or 2 later) and continue right off. That alone is a HUGE advantage for me, especially at work.

The inevitable question for some will be: but which tool should I use?

Thats the wrong question, as the answer is all of them.

Amp is my goto for most things, but I (well, work) pay for Claude and ChatGPT, so I can use both Claude Code and Codex for nothing extra. Amp is pay per token, so you can control your usage really well. Stitch is free, and I get Gemini "free" with Google Workspaces.

We have a policy at work (and home) that we don't pay for annual plans for any of these, and we use token-based payment methods where we can. The space is moving way too quickly to commit to one tool for 12 months, and there are more and more tools around which bill like Amp (eg Autohive). This means they are likely to be sustainable over time, rather than a few users using massive amounts of tokens, which only works when the VCs are paying the bills.

i ran Claude in a loop for three months, and it created a genz programming language called cursed
It’s a strange feeling knowing that you can create anything, and I’m starting to wonder if there’s a seventh stage to the “people stages of AI adoption by software developers” whereby that seventh stage is essentially this scene in the matrix... It’s where you deeply understand that ’you can now

All up, this has been really useful and fun exercise, with a nice set of dopamine hits along the way. If you're in NZ and have to pay RUCs, go give it a try - its free!

Nic Wise

Nic Wise

Auckland, NZ