DEV Community

Vitalii Kiiko
Vitalii Kiiko

Posted on • Originally published at craftformswp.com

When you outgrow Formspree, Netlify Forms, or Web3Forms

If you build static sites, you've used one of these: Formspree, Netlify Forms, Basin, Getform, Web3Forms, staticforms.dev. Paste a URL into a form's action, the service catches the POST and emails you the result. For a single contact form, this is genuinely the right tool — zero backend, minutes to set up, free at low volume.

It stops being the right tool the moment the site grows up.

Where the wall is

The limits aren't bugs, they're structural — a generic catch-all can't do form-specific things:

  • Submission caps. Free tiers commonly sit around 50–250/month.
  • No logic. It's a dumb receiver — no conditional fields, no branching.
  • No pricing. A configurator or quote form needs to compute a total; a hosted endpoint has no concept of that.
  • Weak or paid-tier file uploads.
  • Minimal email templating. You get what they give you, not your brand.
  • Data ownership. Every submission — sometimes with personal details — sits on someone else's infrastructure.

None of that matters for "contact us." All of it matters for registrations, bookings, quotes, orders, and configurators.

The fix isn't "go fullstack"

The instinct is to think you now need a real backend, which usually means abandoning the static site. There's a middle path: run one locked-down WordPress install as a private form backend, with CraftForms as the engine, and keep the static frontend exactly as it is.

Your frontend connects one of two ways — a direct fetch on submit, or an embed (<div> + one script) that pulls the live form from the backend and renders it in place. Either way, that's the only thing the WordPress install does. It's not a website; it's a submission API.

"Isn't running WordPress what I was trying to avoid?"

Fair question, so be precise about what's actually installed: no theme, no public frontend, no page builder, no pile of plugins — the usual sources of WordPress pain and CVEs simply aren't there. Locking it down to just the form endpoints is a single toggle in CraftForms (Headless backend mode): it blacks out the public frontend, closes the REST API to everything but the form endpoints, and disables XML-RPC, all reversible. The pieces a plugin can't do from inside WordPress — hiding the login page, server-level rules — are a one-time mu-plugin and a few server config lines.

And the honest trade-off in both directions: CraftForms doesn't ship a built-in CAPTCHA or honeypot yet either. What you get is origin-bound submissions (the form only accepts posts from your domain), server-side re-verification of anything that matters (a tampered price or stock value gets rejected), and a required-header shared-secret gate. For most sites that's a stronger position than an emailed endpoint with no logic at all — if you need heavy bot mitigation today, weigh that.

The rule of thumb

  • One contact form, low volume, no logic? Use a hosted endpoint. It's the right tool.
  • Many forms, real logic, file uploads, pricing, payments, or data you must own? Move the backend in-house and keep the static frontend exactly as fast as it is today.

The static site was never the problem. The backend was.


I wrote up the full comparison — the limits table, the architecture, and the security trade-offs in detail — on my blog:

👉 When You Outgrow Hosted Form Endpoints

Disclosure: I build CraftForms, the WordPress plugin used here — but the "static frontend, one locked-down WP backend" shape works with any plugin that exposes a REST endpoint and an embeddable form.

Top comments (0)