
To build obsidize I started with a simple—or at least straightforward—problem: convert data stored in JSON files to Markdown.
On paper, conversion between standard formats should be one of the strong points of LLMs. In practice, a direct request to Claude or ChatGPT exposed a familiar disadvantage: their wordy answers and tight context limits. The exported files from Claude were simply too big for the standard web interfaces.
And it wasn’t going to be a one-off operation. I’d keep using Claude, creating new conversations, extending old ones. I didn’t want to manually manage exports each time.
So my scope grew. What I actually needed was a tool that could:
- Convert JSON data to Markdown files.
- Update existing conversations/projects in Markdown with new content, without overwriting edits made directly in Obsidian.
Parsers are supposed to be another strength of LLMs—but the context window ruled out Claude and ChatGPT for this first stage.
That’s when I turned to Google’s Gemini 2.5 Pro. With its huge context window, Gemini had no problem accepting an entire conversation file and proposing a parser in Clojure/Babashka that ran successfully on the first go. Same for the projects file. This is Gemini’s real advantage: not something impossible for other GPTs, especially in agent mode with MCP, but far easier when you just need a quick, working answer.
Now I had two tools/scripts doing essentially the same thing—converting JSON to Markdown—but no update logic.
So I decided to simplify first: solve the conversion problem cleanly before tackling updates.
I spun up a standard Clojure project structure (with deps-new), ported Gemini’s Babashka scripts into namespaces, and asked Claude-Code to turn it into a CLI application.
We discussed the tech stack. For JSON parsing, Claude suggested (and I accepted) Cheshire, a well-established, high-performance library built on Jackson.
Then came the real challenge: implementation choices.
Copilots tend to overdo it. They generate too many options, and every option looks equally viable. The risk is saying “yes” too often and ending up in a swamp of half-working approaches. If you already know the right solution, you can use AI just to speed up coding—but that underuses the tools. If, like me, you often don’t know the right approach, you need to push back and test constantly. Otherwise you get caught in endless loops of “ah, I see the error / the issue is still there.”
With Gemini’s proof-of-concept already working, I just needed to refactor and add a few key features:
- Detect input as either an archive (zip/dms) or folder.
- Tag and link imported notes for Obsidian.
- Most importantly, detect already-imported notes and update them without overwriting edits in Obsidian.
At this point, what started as “tidying up my notes” turned into a small personal quest. I wanted to scratch my own itch, but also to try this new way of building software with new tools. Luckily, my vacation plans were simple: kids, grandparents, clean air, fresh food, plenty of sun.
After about two hours of effective work—spread over three mornings—I had a working Clojure project. Not packaged, but functional. It had documentation, unit tests, and just enough features to be useful.
One incidental advantage of working in VS Code with Gemini and Claude-Code: context switching was painless. Every morning, I could skim the conversation history, remember where we left off, and pick up seamlessly. When the kids woke up, I’d close the lid and shift gears. The next morning, my virtual coworkers were still waiting, ready to continue as if nothing had happened.
With the basics so easy to conjure with digital assistants—and mornings still left in my vacation—I felt confident enough to push toward a real app. The linter and automated tests were already there, but I wanted more:
- Add antq to ensure up-to-date libraries.
- Add Trivy for vulnerability and license scanning.
- Build native images for macOS and Linux using GraalVM.
- Make it installable via Homebrew.
That last step—going from project to product—turned out to be the hardest.