Before anyone asks—no, I didn't lose my job, and no, I'm not job hunting. I'm simply between client engagements at my consulting firm, which gave me the perfect excuse to scratch a long-standing itch: building a tool that actually works the way I want it to.
My previous client had strict "no AI" policies, so while everyone else was exploring the latest AI tools, I was stuck on the sidelines. Now that I'm on the bench (consultant-speak for "between projects"), I finally had the chance to dive in and "vibe code" something useful.
The catalyst was simple frustration. Being on the bench means updating company resumes for future engagements, and I've always hated wrestling with Pages, Word, or Google Docs when all I really want is to write in Markdown. Why force myself into clunky WYSIWYG editors when there's a better way?
Armed with an idea and Claude Sonnet 4, I set out to build a resume tool that would make my life—and possibly yours—a little easier. In less than an hour I had a working prototype. In less than another hour, I had something approaching production-ready. Here's how it unfolded, complete with the lessons learned along the way.
Getting Started
My opening prompt: "I want to write a local running package that can take markdown resumes and output them into pdf files, also should be able to style them using a theme."
And just like that, we were off to the races. The first attempt seemed promising, but I'd made a classic mistake: not being specific about my preferred tech stack. Claude defaulted to Python, and while that's probably perfect for this kind of tool, I know virtually nothing about it. Future feature additions would be a nightmare.
Time to course-correct with some context.
Follow-up prompt: "I know little to nothing about Python, can this package be JavaScript or TypeScript based? Also, I would prefer to use bun for the package manager and Vite for the build tool."
Claude's response: "Absolutely! I'll recreate this as a JavaScript/TypeScript package instead. Let me update the plan and rebuild the project using Node.js technologies."
Now we were cooking. The initial scope was straightforward: a command-line tool that takes markdown input and spits out styled PDF output. For my needs—and likely most markdown enthusiasts—this would be perfect. We hit a minor snag with Puppeteer installation hanging, but worked through it quickly enough.
The First Real Challenge
Theming came next, which was relatively smooth sailing. But then we encountered our first meaningful problem: experience blocks getting awkwardly split across pages. This is the kind of formatting nightmare that makes you add random line breaks just to keep things readable—something I'd dealt with in other resume tools before.
Using some targeted CSS and tweaks to the markdown renderer, we managed to keep content blocks intact. Small victory, but it felt significant.
Scope Creep Sets In
Here's where I really put Claude Sonnet 4 through its paces. What started as a simple CLI tool suddenly needed a preview interface. Why write blind when you could see your changes in real-time?
So we built a web UI for live editing and theme previewing. Once that was working nicely, PDF export from the browser seemed like an obvious next step. Again, surprisingly straightforward.
At this point, I could have called it done. But then I started thinking about the real world.
The ATS Reality Check
ATS systems prefer Word documents over PDFs. They also favor basic fonts and semantic structure over beautiful design. Since I was building a resume tool in 2025, ignoring ATS compatibility would be like building a website that only works in Internet Explorer 6.
So we added Word document export and a real-time ATS warning system for the frontend. This proved trickier than expected. We cycled through several libraries before settling on docx, which handles most cases well but has some limitations. The lack of proper list item support means our page-break prevention strategy falls apart in Word exports, requiring manual cleanup.
It's not perfect, but it's functional. The PDF output remains the star of the show, and the tool accomplishes what I set out to build: a way to write resumes in Markdown without fighting against the tooling.
I rounded things out with Vitest for testing, Prettier for formatting, and ESLint for code quality—because even vibe coding deserves best practices.
What I Learned
The whole experience felt less like traditional coding and more like having a conversation with a very capable colleague. Instead of wrestling with documentation or hunting down the right Stack Overflow answer, I could describe what I wanted and iterate on the implementation. When scope crept (and it definitely did), Claude adapted seamlessly.
The key was being specific about constraints and preferences upfront, then maintaining that context as the project evolved. When I hit limitations—like the Word export issues—Claude was honest about trade-offs rather than overselling solutions.
For a few hours of "vibe coding," I ended up with a tool that actually solves my specific problem. Not bad for a lazy afternoon on the bench.
The Final Product
What started as a simple markdown-to-PDF converter ended up as a full-featured resume builder. CVCraft now handles both PDF and Word document exports, features a real-time editor with live preview, and includes an ATS compatibility checker that warns you when something might trip up applicant tracking systems. The theming system lets you customize the look and feel, with color overrides available right in the UI for quick tweaks.
Most importantly, it solves my original problem: I can write resumes in Markdown without fighting the tooling. No more wrestling with WYSIWYG editors or worrying about formatting breaking when I make a simple text change.
For a few hours of "vibe coding," I ended up with a tool that actually solves my specific problem. Not bad for a lazy afternoon on the bench.
Want to try it out?
You can find CVCraft on GitHub. Or install it globally via npm: npm install -g cvcraft
. Give it a try and let me know what you think!
No comments yet, add yours here.