DripSharp: Building a Java-to-C# source converter with AI - Isak Sky's blog
Isak Sky's blog
Clojure, SQL, and more
DripSharp: Building a Java-to-C# source converter with AI
Posted at — Aug 20, 2026
A few months ago, Jarred Sumner ported Bun from Zig to Rust with AI, largely processing one file a time. While it was a cool thing to try, and I’m sure there are many reasons why this made sense for him to do it this way, it didn’t strike me as a great general way to tackle this kind of problem.
I am definitely for using AI where possible, but my instinct was that a better way to do this is to just create a program that walks the syntax tree of the source and applies a bunch of rules to transform it node by node.
A few reasons why this is better:
You get not only the converted code, but also a reusable converter you can use again later for other projects, without an LLM having to be involved.
Each transformation rule gets more and more battle-tested. If a rule has transformed 5,000 string operation call sites across multiple projects with tests passing, we can trust it more than a single call site vibe-transformation.
You can add optimization / beautification layers later, and run it again and get better outputs almost for free.
In general, determinism and verifiability are stronger. There is less chance of a costly AI hallucination, or a particular model having a blind spot. Not quite as stark as the difference between asking AI to manually sum a thousand numbers versus having it write code to do that, but along those lines.
Lower token costs. More on this below.
I decided to let AI (ChatGPT 5.5 and later 5.6) have a go at this. For my day job, a lot of my work is in the .NET ecosystem, and we saw that some problems are better solved in the JVM open source ecosystem. I went for a Java to C# code converter, using Clojure as the implementation language, since that is the JVM language I use the most.
To get started, I set up the main dependencies needed (e.g., Spoon for Java parsing), and wrote documentation for the project goals and architecture with AI assistance. For issue tracking I used beads_rust.
At first, I tried a more elaborate workflow. It went like this:
Select a Java project.
Create a JVM feature inventory (e.g., Java switch, myMap.put(...), etc.) list of the project, and put it in a database (Datomic).
Implement/fix handlers for every missing feature.
Try converting the project. If it fails, throw the incomplete result away, and create beads for the bugs, then go back to 3.
If it succeeds, go back to 1.
This ended up not working, and I had to throw away more than 1,000 commits. The agent went with a regex/string conversion engine, and iteratively narrowed the project goals down to almost nothing and declared victory.
A large part of why that failed may be that I tried Codex’s /goal mode for this, which at least in my case seemed to keep doubling down on poor decisions, and never “taking a deep breath” and reconsidering whether the direction it was taking was working out.
After throwing that out, I did a few sessions interactively on extra-high reasoning to get it started further in the right direction. ChatGPT 5.6 also dropped around this time, which appeared to help power through the initial logic-heavy work of handling each Java statement/expression type. The workflow that ended up working was a loop orchestrated by a small Babashka script:
Are there any tasks ready in beads? If so, have the agent do that task.
No tasks ready? If so, examine the documentation (architecture and project goals), and plan (with extra-high reasoning) the next epic bead with subtasks. If the project is done, signal that. The script harness will stop the loop.
Towards the end, I switched to doing the planning interactively to make sure it wasn’t wasting time on things that did not matter.
After about two months of cranking on this with Codex, mostly unattended, it can now convert multiple non-trivial projects (PDFBox, Pkl, JSqlParser) and run tests successfully.
I think PDFBox is especially valuable. At work, we cobbled together 3 open-source .NET libraries to approximate the feature set we needed, and we were still missing some parts available in PDFBox, like working with PDF forms. In the ported version, PdfCarton, all 232 upstream test files for the modules I targeted have been ported, and my latest run had all 2,243 runnable tests passing. The remaining 8 were skipped for the same reasons as upstream.
Not all of the projects worked out that cleanly yet. For example, while the core of Pkl is written in Java, it had tests written in Kotlin, which this project cannot (yet?) handle. For now, the mechanically ported coverage is incomplete, but there are extensive LLM-authored tests, leveraging the existing .pkl test files as much as possible.
All in all, it came out to about 110 KLOC of Clojure, and used up most of my budget for a personal OpenAI 20x Pro plan ($200/mo) for two...