ALL WORK
[CASE STUDY][OPEN SOURCE — MIT]

Formto

A self-hosted form backend — add one action attribute to any HTML form and submissions land in your dashboard. MIT-licensed, asleep by choice, still running.

TIMELINE
V1.1.0 — APRIL 2026
TYPE
OPEN SOURCE / SELF-HOSTED
STACK
REACT 19 / FASTIFY + NODE 20 / POSTGRESQL 16 / DOCKER + CADDY
STATUS
[OPEN SOURCE — MIT]
Formto

The itch

Every static site eventually needs a contact form, and every contact form eventually needs a backend. The SaaS options — Formspree, Formcarry, Basin — work fine until you hit the pricing tier wall, the submission cap, or the simple discomfort of your leads living on someone else’s servers.

Formto is the self-hosted answer: one action attribute on any HTML form, and submissions start collecting in your own dashboard, on your own domain, in your own database. No coding, no subscription, no vendor lock-in.

What’s in the box

More than a dumb inbox:

  • Submission management — read/archive/reply, statuses (new / in-progress / resolved), internal notes, tags, search and filters.
  • Notifications everywhere — email via any SMTP (Gmail, Mailgun, Postmark, Resend), native Telegram bot, Slack webhooks, and custom JSON webhooks for Zapier, Make, n8n, Discord.
  • Spam defense — honeypot detection, rate limiting, IP/email/domain blocking, auto-close after N responses or on a date.
  • Data ownership — CSV/JSON export, submission analytics, per-form performance, top-fields breakdown.
  • Hosted form pages — no site? Every endpoint gets a standalone form page at /f/:endpoint.

Formto flow — any HTML form with one action attribute posts to your server, where Formto stores, protects and routes submissions to email, Telegram, Slack and webhooks

Deployment is the product

The whole pitch collapses if self-hosting is painful, so the setup is three steps: clone, fill a three-line env file, docker compose up -d. Caddy handles HTTPS automatically via Let’s Encrypt, a first-run wizard does the rest, and schema migrations run themselves on update.

Who it’s for

  • Static sites and JAMstack builds that need exactly one dynamic thing,
  • agencies running dozens of small client sites who’d rather pay one VPS bill than thirty SaaS subscriptions,
  • anyone with data-locality requirements — the leads never leave a server you control, which makes compliance conversations short.

Boring, auditable choices

React 19 + Tailwind v4 front, Fastify on Node 20, PostgreSQL 16, JWT auth, bcrypt, SSRF protection with DNS pinning, 100% parameterized SQL — the right kind of unexciting for software that holds other people’s leads.

Asleep by choice

I stopped developing Formto — it didn’t take off as a project I wanted to push, and pretending otherwise would cost attention my live products need. But “stopped developing” is not “dead”:

  • The code is MIT-licensed on GitHub — fork it, ship it, sell it.
  • It runs in production unattended; the last release (v1.1.0, April 2026) added a dark theme and bug fixes.
  • Strangers still find it, star it, and deploy it — which is exactly what open source is for.

Of my five shipped products, Formto is the one that’s asleep: useful to others, zero claim on my week. Open-sourcing was the honest way to put it to bed — a public repo teaches somebody something every month; a private one teaches nobody anything.