A Netlify Forms alternative that doesn't lock your form to Netlify hosting
Netlify Forms has a reputation, earned over several years, for being cheap to start with and expensive to outgrow: 100 free submissions a month, then a per-level overage charge once you cross it. As of writing, that's no longer quite the full picture — Netlify moved to credit-based pricing for accounts created after September 4, 2025, and under that model, form submissions themselves are free and unlimited. Accounts created before that date are still on the legacy metered plan, with the old ~100/month free-tier cap and paid overage tiers, unless they've since migrated. (Checked against Netlify's own docs 2026-07-15 — see sources at the end.)
So the pricing angle is narrower than it used to be, and we're not going to pretend otherwise. What hasn't changed is the lock-in: Netlify Forms only works because Netlify's build step scans your deployed HTML for a specific attribute and wires up serverless handling behind the scenes. Move your site off Netlify — to a different static host, a different framework's dev server, anywhere Netlify isn't doing the build — and the form silently stops working. There's no action URL to port; the entire mechanism is proprietary to Netlify's build pipeline.
A plain HTML form that posts to an external URL doesn't have that problem. It works identically whether you're hosting on Netlify, Cloudflare Pages, Vercel, GitHub Pages, or your own server, because the form doesn't know or care who's serving the page — it just POSTs somewhere.
Why Netlify Forms is build-coupled
To use Netlify Forms, your form needs a data-netlify="true" attribute, and if the form is rendered client-side (React, Vue, any JS framework), you additionally need a static, hidden duplicate of the form in your HTML so Netlify's build-time bot can detect the fields — a documented workaround, not an edge case. Netlify Forms also only accepts URL-encoded bodies; JSON submissions aren't supported. None of that is wrong, exactly — it's just specific to how Netlify's infrastructure works, and it means your form markup carries Netlify-specific plumbing that has no purpose anywhere else.
The alternative: a plain form, no build step involved
<form action="https://api.submissionbuddy.io/f/your-form" method="POST">
<label>Name <input type="text" name="name" required /></label>
<label>Email <input type="email" name="email" required /></label>
<label>Message <textarea name="message" required></textarea></label>
<!-- honeypot: hidden from humans; bots that fill it are silently dropped -->
<input type="text" name="_honeypot" style="display:none" tabindex="-1" autocomplete="off" />
<!-- where to send the visitor after a successful submit -->
<input type="hidden" name="_redirect" value="https://your-site.netlify.app/thanks/" />
<button type="submit">Send</button>
</form>
Drop that anywhere on a static Netlify site — no data-netlify attribute, no hidden duplicate form for JS-rendered pages, no build-time scanning required. Get an endpoint first (free, no credit card), swap in your form slug, and it's live. Field names are yours to choose — there's no schema, so adding or renaming a field never requires touching the form config on SubmissionBuddy's side, unlike Netlify's build-time field detection.
Prefer to stay on the page instead of navigating away? Use fetch and skip the _redirect field:
const res = await fetch('https://api.submissionbuddy.io/f/your-form', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email, message }),
})
if (res.ok) {
// 202 { "ok": true, "submission_id": "…" }
showSuccessMessage()
}
JSON, application/x-www-form-urlencoded, and multipart text fields are all accepted — Netlify Forms only takes the second of those three.
What happens after submit
The submission is written to durable storage before anything else touches it or the browser gets a response back. From there it flows through independently retryable stages: a database write (searchable and exportable from the dashboard) and an email notification to your team — a hiccup in one stage doesn't drop the submission or block the others. Per-IP and per-form rate limiting are on by default on every plan alongside the honeypot field above; paid plans can add an invisible, self-hosted CAPTCHA (no third-party calls, no cookies) for more determined bots — Netlify's equivalent is a reCAPTCHA 2 challenge, which does bring in a third-party script.
Where this doesn't help you
If you're already deep into Netlify's ecosystem — form-triggered serverless functions, the Google Sheets/Slack integrations built on Netlify Forms, or you're on a credit-based account where forms genuinely cost nothing extra — switching just to save money isn't the right reason to do it. The case for an external endpoint is portability (your form works the same regardless of host) and a real dashboard: full-text search across submissions, date-range filtering, sortable columns, and an Excel export, none of which Netlify's basic forms panel provides natively.
The free tier
Sign up free — 100 submissions/month across up to 2 forms, no credit card required.
Netlify's forms and billing documentation checked 2026-07-15: Forms usage and billing, Billing FAQ for credit-based plans ("Form usage is free and unlimited" on credit-based plans, "no submission limits or tier levels for forms"), Billing FAQ for legacy plans (accounts created before September 4, 2025 are on legacy metered pricing), and Forms setup (data-netlify attribute, hidden static form requirement for JS frameworks, URL-encoded-only bodies). Code samples verified against the live SubmissionBuddy API the same day.