ReplyForge is a self-hosted REST API that gives your blog a fast, private comment system with built-in moderation and Turnstile spam protection.
They slow down your sitewith heavy scripts and tracking.
Your readers' datalives on someone else's server.
Spam moderationis an afterthought or locked behind a paywall.
You lose controlover the user experience and styling.
There's a better way. Meet ReplyForge.
You Own the Database— Comments are stored in SQLite. No external service, no lock-in. Backup, query, and export as you like.
Spam Without the Captcha Pain— Cloudflare Turnstile verification runs invisibly. No puzzles, no friction. Token verification is fast and cache-efficient.
Moderation Built In— Every comment lands in a pending queue. Approve, delete, or toggle from a simple admin panel protected by a password.
Lightweight & Fast— A single Go binary, 20 MB of memory, negligible CPU. Works on the smallest VPS, even on a Raspberry Pi.
Email Notifications— Get pinged when a new comment arrives, so you don't have to check the dashboard.
Developer-Ergonomic API— Predictable JSON, clear error codes, request IDs for tracing, and configurable CORS. Designed to be called from any static frontend.
through your HTML form (with Turnstile widget).
marked as unapproved.
via the admin UI or API, and it's publicly visible.
Everything is synchronous, no queues, no extra infrastructure. Just HTTP.
Clean, no-frills moderation from your browser. One password, no accounts.
Endpoints also available for automation— integrate with your CI or custom scripts via the admin API.

Every error follows the same JSON structure with a machine-readable code, human-readable message, and per-field details. A unique X-Request-ID header on every response makes tracing trivial.
Per-IP rate limiting with configurable requests-per-minute and burst capacity. No external Redis required — the limiter runs entirely in-process. Exceeding the limit returns a clean 429 Too Many Requests.
author_name and body are sanitized before they ever touch the database. Every input is trimmed, HTML-stripped, Unicode-normalized, and purged of null bytes — automatically.
display_id in Every ResponseEvery comment gets a short, unique identifier generated via sqids. Use it in URL fragments, client-side references, or anywhere you need a compact, user-friendly pointer to a comment.
Point your static site's JavaScript to https://example.com and you're done.
No Docker? Download the single binary. No database to install; SQLite is embedded.