We all have those personal projects we started with great enthusiasm, only to leave them gathering dust in our computer folders because of the pressures of life. The Japanese have a wonderful word called "tsundoku," which describes a pile of books you buy with the intention of reading them someday, but which accumulate without ever being opened. Well, as programmers and tech enthusiasts, we have our own "tsundoku" of unfinished code. These abandoned projects are the perfect testing ground for the capabilities of AI-powered programming assistants, because, after all, we would never have finished them without these tools.

The idea and preparation for the task
In the past, I started a project that was essentially a middleware layer (Shim) connecting YouTube Music to the OpenSubsonic API. In short, OpenSubsonic is a great software node that separates music streaming servers from the applications that run them, allowing you to choose your preferred mix. Personally, I prefer using Navidrome as the server, Feishin on PCs, and Symfonium on Android. The idea was to make YouTube Music compatible with this API so I could integrate it into any of my favorite apps. While getting the basic stream working was easy using ytmusicapi and yt-dlp, implementing all the necessary functions was tedious, and, as usual, new projects caught my attention.

Fortunately, this streaming project wasn't overly complex, and there were clear specifications to follow, making it ideal for experimenting with AI-assisted programming. I decided to test Cloud Code (the Opus 4.6 model) using $50 in free credits to build the project from scratch. I set up the environment using FastAPI and Pydantic, and provided Cloud with OpenSubsonic's OpenAPI specification file, as well as a CLAUDE.md file containing strict guidelines, such as using the latest Pydantic technologies and writing professional unit tests, to prevent it from repeating common mistakes.
Building the Initial Version (MVP)
With everything set up, I let Claude take the lead. The process involved going into planning mode, asking him to complete the next step, reviewing and correcting the plan, and then giving him the resources to troubleshoot when he encountered obstacles. My first request was straightforward: “Take a look at the openapi.json file. Implement a server using fastapi that sets up stubs for all the required functions, focusing only on modern JSON paths.”

Even with clear specifications, Claude made some initial errors, but managed to correct them on the second try. The next big step was requesting the app to connect, search for a song, and stream it. I quickly got a logical implementation, but it faltered when trying to actually connect to the Feishin app. This is where iterating and tweaking came in; I ran the app and passed the error logs to Claude Code. Amazingly, after a few iterations, I was actually listening to music streaming through Feishin! The main hurdle was having to return empty but properly structured responses instead of nothing at all.
Final touches and tedious tasks
Getting the initial version was the easy part, but the real challenge was dealing with the tedious and cumbersome tasks (the long tail) of making the project usable. The OpenSubsonic interface contains approximately 80 tracks divided into 15 categories. To ensure my server ran at full capacity, I used AI to implement a simple caching system to avoid exceeding the YouTube API limits, and I used SQLite databases to store the music metadata.

The work also included saving songs to a disc while streaming to avoid repeated downloads, along with special code to clean up incomplete files if the connection dropped before the download was finished. These were all things I knew needed to be done to make my old project useful, but I'd never done them because I found them cumbersome. In a short while, thanks to artificial intelligence, I had a service that worked perfectly, which I jokingly called "Sub-standard."
Is this approach healthy for programmers?
I don't want to sound like a blindly enthusiastic proponent of AI programming. I still have concerns about losing programming skills due to over-reliance on these tools. That's why I still insist on trying to learn a complex language like Rust on my own. We should categorize our personal projects into two boxes: the first is "things I do to learn and develop my skills," and the second is "things I truly wish existed and were available to me."

This project clearly falls into the second category. Using AI to achieve these projects is a form of wish fulfillment. I would never have completed it on my own, but now I have a fully functional project and one metaphorical book that has been read instead of gathering dust on a shelf. Ultimately, what matters is not completing the projects you wish for using AI, but ensuring that you continue to invest your time in the projects of the first category to develop your own skills.
Source:



7 comment