I shipped a tool that generates conventional commit messages from any git diff. No signup wall, no API key, no subscription. You paste a diff, you get a commit message. That's it.
The live tool is at https://commit-msg-ai.solomontools.workers.dev. Go try it right now — paste any diff from a git diff output and watch it write you a commit message in seconds.
Here's why I built it, how it works, and what I learned along the way.
Why I Built It
I hate writing commit messages. Not because I don't care about good commits — I do. But every time I finish a coding session, I'm tired, I'm context-switching, and I have to manually parse a diff I just spent hours writing to figure out what to type into the commit box.
I looked at existing tools and found a pattern: most either required you to sign up, connect a GitHub repo, or pay a monthly subscription for what should be a trivial text-generation task. That felt wrong. A commit message generator should be as frictionless as git commit -m.
So I built one that runs entirely in the browser and edge, with no accounts, no tracking, no paywall behind a registration wall.
How It Works
The architecture is deliberately simple. There are three pieces:
- A static frontend (HTML + vanilla JS) that lives on a CDN and lets users paste a diff and hit "Generate."
- A Cloudflare Worker that receives the diff text, calls an AI inference endpoint, and returns a formatted conventional commit message.
- No database, no auth layer, no state. The entire thing is stateless.
The worker sits at the edge, close to users, and handles the AI request in a single serverless invocation. Here's the core routing logic:
// Cloudflare Worker entry point
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/api/generate" && request.method === "POST") {
const { diff } = await request.json();
if (!diff) return new Response("Missing diff", { status: 400 });
const message = await generateCommitMessage(diff);
return new Response(JSON.stringify({ message }), {
headers: { "Content-Type": "application/json" },
});
}
// Serve the static frontend for everything else
return fetch(request);
},
};
The generateCommitMessage function sends the diff to an AI model with a tightly constrained prompt. The prompt enforces conventional commit format — type(scope): subject — and asks the model to analyze the diff for added files, removed files, and changed logic to determine the appropriate type (feat, fix, refactor, docs, chore, etc.).
The frontend is intentionally minimal. No framework, no build step, no bundler. It's a single HTML file with a textarea, a button, and a result area. The total payload is under 5KB. It works on any device, any browser, even offline-ish if you've cached it.
Why Cloudflare Workers
I considered a few deployment options. AWS Lambda would work but cold starts are annoying for a tool that should feel instant. Vercel Serverless Functions are great but lock you into their ecosystem. A Docker container on a VPS would require me to manage infrastructure.
Cloudflare Workers hit the sweet spot for me:
- Edge execution — sub-50ms cold starts, globally distributed.
- Free tier — generous enough for a side project with modest traffic.
- Static asset serving built in, so the frontend and API live in the same worker.
- No vendor lock-in — the code is standard JavaScript, easy to migrate anywhere.
The AI inference itself happens via a third-party API call from within the worker, so the worker is really a thin orchestration layer. It receives the diff, formats a prompt, calls the model API, parses the response, and returns JSON. Total latency is usually under 2 seconds.
What I Learned Shipping This
Keep the frontend stupid. The temptation was to add a React app, a settings page, history, themes. None of that matters for a tool that takes 10 seconds to use. A <textarea> and a <button> are the best UI for this product.
Prompt engineering matters more than model choice. I tested a few models and found that a well-structured prompt with explicit output format instructions produced better results than switching to a larger model with a vague prompt. The conventional commit format is rigid enough that you can heavily constrain the output and get consistent quality.
Statelessness is a feature, not a limitation. Not having a database means no migrations, no backups, no scaling concerns. It also means there's no way to lose user data because there's no user data to lose. That's actually a design strength for a disposable utility tool.
HTTPS everywhere, always. Since the frontend is static and the API is served from the same domain, CORS is simple. But I also set strict CSP headers and force HTTPS redirects in the worker. Security is cheap insurance.
Cost and Monetization
This tool is free to use. There's no signup, no tracking, no data collection. It runs on Cloudflare's free tier and the AI API costs are covered by my own usage during development.
If you find it genuinely saves you time and want to support the project, there's a one-time $5 option on the landing page. That's it. No subscription, no tier system, no "upgrade to remove this banner." If it saves you 10 minutes a week, that's $5 well spent. If it doesn't, keep using it for free — I'm not going to bother you about it.
Build things that are useful, ship them simply, and don't monetize what shouldn't be monetized. That's the philosophy behind this project, and I intend to keep it that way.
Enjoyed this? I build simple, powerful AI tools — try the free Text Summarizer or browse the full toolkit at Solomon Tools. No signup, no subscription.
Top comments (0)