OddTurnip logo OddTurnip

A simple philosophy: Claude handles the code; I verify the outputs.

I’ve spent the last couple of years using LLMs as my primary method of building software. Part of this is practice and education; the goal is less to build universally useful software and more to show what an LLM-centric workflow can accomplish today. As a bonus, it’s a great chance to build a bunch of little utility apps that help my day to day tasks.

This site is an archive of that journey: short write-ups of each project, what it does, how it was built, and where the code and the running version live. Some of it is for tabletop gaming, some is developer tooling, some is infrastructure. All of it is real, deployed, and in use.

The number one lesson I’ve learned is that being a good developer now looks a lot like being good at Quality Assurance - you need to be comfortable testing the flow of the code, and finding the unhappy paths that the unit tests miss. You also need the patience to slog through 99% of the features working to find the 1% that went wrong.

Programming experience still matters, though - I can immediately get a feel for a lot of errors in the code simply based on the behavior. These two numbers don’t match, which means there’s a DRY (Don’t Repeat Yourself) violation in there somewhere. Knowing when a build has gotten complex and messy, and pushing the LLM to do an architectural review. Getting a feel for when technical debt is building, and running a debugging session.

In the end, I think Agile is the most important principle. Writing a quick prototype with disposable code to test a concept is exactly where LLMs are ideal. They’re great for rapid iteration and playing around with ideas. Test, iterate, repeat. For example, when building TurnipText, I could easily try out all sorts of wild ideas, spend a few minutes seeing if I liked it, and either reverting or iterating forward.

LLMs drop the cost of exploration to near-zero, and I think that’s one of the most overlooked benefits. Once you’ve proven the concept works, it’s a lot easier to fine-tune performance, or even start over entirely with a performance-centered rewrite.

TurnipText is a text editor shaped around how I personally work

A small, opinionated writing tool with exactly the features I use and nothing I don’t.

What I learned: It’s ugly but it works exceptionally well for me. It feels a bit clumsy any time I have to use a non-bespoke Text Editor now. I think in a few years, this sort of bespoke customization will be normal for a wide range of applications - I can ask Claude for a new feature and be using it 5 minutes later.

Toolbox: single-page web utilities

A collection of basic tools like word count, text diff, and some surprisingly capable image manipulation tools. Plenty of similar collections exist, but this one has everything I need and nothing I don’t.

What I learned: it’s remarkably easy to build simple single-purpose image manipulation websites, and they work much faster than a dedicated multi-purpose application.

WebArcade: a weekend of classic games in the browser

A small arcade of browser games with sound effects, music, and gamepad support. Built in a weekend to see how far Claude could get with minimal one-shot prompts like “create Tetris”, “add support for my XBox controller” and “compose some music and SFX”.

What I learned: with minimal specification, it usually took me a second prompt to actually be fully satisfied with the output, but only Tetris had a bug (a race condition where rotation should allow falling to continue, but it had already “locked” into place - solved by prompting it solely with a description of the behavior). In short, these tools have a surprisingly good sense of context, and understand what sort of features each game should have - high scores, etc.

Gaming tools for my weekly tabletop group

Dice rollers, a SQLite-backed name generator, and digital character sheets for Blades in the Dark, FATE, and a homebrew system - built to solve real friction at our actual game table.

What I learned: I’ve built these in a few different languages over the year, so I know the perils well. I was quite impressed with the LLM’s accuracy here, and especially their ability to build unit tests around random number generators - which tends to require both stubbing the Random function AND being willing to run technically “unreliable” statistical tests. For my personal code base, a one in a million “flaky test” is quite acceptable to ensure everything really does work when a non-mocked Random is plugged in.

Bonus: LLMs are also a pretty solid source for populating a database of random names, and the database / variety helps shake them out of their otherwise slightly eccentric naming tendencies.