YNAB is my budgeting tool of choice. It works, and I don’t want the hassle of maintaining my own instance of Actual Budget .
YNAB has support for Open Banking sync, which I do use. However, their API vendor, TrueLayer, continues to lack Chase UK Open Banking support, despite it being available for ~1 year now. Other tools, like Moneyhub, have supported it for yonks now.
Using the direct bank API yourself is impossible (regulatory requirements), but you can use a intermediary vendor. GoCardless is particularly cool because they offer free access (albeit limited), something with Actual Budget uses for their sync implementation. It should be easy to replicate this for YNAB.
With some spare time, and a desire to dig into agentic LLM tools, I decided to give it a shot. I’m pretty happy with the outcome.
Desires
- I didn’t want to pay anything additional (I’m trying to budget here…),
- I wanted the tool to be local-only: that way, I only have to trust GoCardless & YNAB.
This ruled out the already existing GoCardless-based tool, Synci. I’m sure it absolutely works great, has a bunch of features my tool will never have, and is risk-free. But better to be safe than sorry.
- Doesn’t need to be particularly user-friendly. While I made the best attempt to make it user friendly (as much as a CLI tool can be), the only person it has to be work for is me. Anyone else is a bonus :).
Thoughts while building this,
This project was built a lot on vibe coding. It was a fun experiment, and after some effort, absolutely got me where I wanted to. On the way, I learned a bunch of stuff.
- At work, I’m currently using Roo Code (primarily because our only AI tech is access to a Claude API key). Roo is pretty good, and absolutely does the job.
- But man, Cursor is awesome. The UI is beautiful, and the agentic implementation seems to be just a bit better than Roo. It has the extra layer of polish. Genuinely tempted to shell out for Pro whenever I work on a new project (without Cursor, I’m just manually shelling out for Claude tokens).
- Oh, and the completions are actually really good.
- AI can do a lot of the scaffolding right.
- When the conversation becomes too long, it completely fails to do anything novel or interesting. Kaparthy’s recent video on LLMs comes with a great explainer for this behaviour.
- Cursor rules are great in theory, but I couldn’t get it to click.
- For instance, I asked it to never suggest installing something, and yet it continued to do so.
- I asked it to use uv to do package management and program invoking. It sometimes did.

- I’m not pretending my instructions are even good, but argh, this is frustrating.
- For a bit, I went purely YOLO, and let it go purely agentic… this had some bad results,
- It installed a bunch of crap to my system pip in a vain attempt to get packages right.
- (The issue here was a bad Python version: 3.8 was too old for some of the packages, and 3.13 was too bleeding edge for many to have distributions: on 3.13, there is no numpy version so it kept trying to compile it, which is a recipe for disaster on Windows).
- Interesting quirks,
- It sometimes get stuck in using older tech.
- For instance, when it, out of its own volition, implemented a progress bar, it decided to use
tqdminstead ofrich(which was already added to the project). - And practically everytime it wanted to get the current date, it used
utcnow(), instead ofnow(datetime.UTC). - The initial plan suggested
requests. Nothing wrong withrequests, but I findhttpxa much better choice.
- For instance, when it, out of its own volition, implemented a progress bar, it decided to use
- It could not resolve an issue where a particular bank account would randomly bomb out: the underlying source being the default
httpxtimeout of 5 seconds. - It used
httpxclients… but insisted on creating one for every request. That’s basically pointless. - The tool used
asynciofor the implementation. Nothing wrong with that, but wholly unnecessary for a project only performing one REST request at a time (I suspecthttpxis linked quite heavily withasyncio, so it felt like it had to use it). - Disappointed it never attempted to use dataclasses, until I prompted it to do so.
- For some reason, it hallucinated that the YNAB API did not accept negative numbers (it does, and you need to use negative numbers for outflow). I suspect this is because YNAB doesn’t support negative numbers, but that’s because it forces you to use a double-entry bookkeeping style in the UI.
- It sometimes get stuck in using older tech.
- GoCardless’ API limits made debugging issues a pain.. but equally, I should have intervened with my own abilities far earlier. One of the problems of vibe coding is that it is very easy to forget your own cognitive ability. I find I have this problem less at work, likely because I use it less & have to intervene way more often. Simon Willison’s recent take roughly aligns with what I’m thinking.
xkcd #1205
Historically, this sort of project I wouldn’t have looked at due to the unlikely nature I’d save any time here. As much as it seemed cool, I had other projects I wanted to prioritise.
But LLMs change the dynamics a lot: it takes substantially less time to get you almost there.
That being said, you’ve still got to read everything it outputs, build up that mental model, and get stuck in if is unable to deliver the proper solution, which, even in a relatively simple like this one, I find it does shockingly often.
Either way, I’ll be exploring more ideas that come to me with this tech, and I think that’s a really neat outcome.