How to self-host a Formspree alternative on Cloudflare
Start with FormZero's reviewed source and a separate test database. Its deployment script builds the application, applies remote migrations and deploys a Worker. Before moving a live form, validate authentication, submission responses, spam controls, exports and any optional SMTP notifications.
By Cloudsteading · Sources checked 2026-10-02 · Independent guide
Inspect the pinned deployment before running it
Open the FormZero project page and follow its pinned repository links. The reviewed commit is a4ddde255457d1e6ddf55b5f24b51809d18501f3. Its Wrangler file points to workers/app.ts, enables Node compatibility and declares D1 as DB. Replace the repository's database ID with a database owned by your account. Keep the pilot separate from any existing production data.
The package's deploy script builds with React Router, applies migrations with --remote and then runs Wrangler deploy. It is a remote mutation, not merely a local preview. Inspect the SQL and intended binding first; create a backup before applying migrations to a populated database. This guide did not run the upstream script.
Follow the actual submission path
The Worker delegates requests to the React Router application. The submission route looks up a form in D1, parses JSON or form data and inserts a submission record. For JSON clients it returns a success response; HTML clients use a redirect path. The reviewed configuration does not add KV, R2 or a Queue merely because those services are available on Cloudflare.
| Layer | Evidence | Pilot check |
|---|---|---|
| Browser form | HTML/JSON parsing in the route | Match the content type, expected response and thank-you destination |
| Worker | React Router request handler | Check build output and correct deployment binding |
| D1 | DB and SQL migrations |
Confirm tables, ownership and access with two synthetic accounts |
| Authentication | Package-declared BETTER_AUTH_SECRET and application auth code |
Verify the secret reaches the auth system; test login, logout and cross-account isolation |
| Optional SMTP | Notification helper and global settings | Confirm credential handling, provider requirements and actual receipt |
Treat notifications as a separate delivery test
Begin without real SMTP credentials. The pinned code reads notification settings from D1 and schedules email work after storage. It catches notification errors rather than making delivery a condition of submission success. A dashboard record and a successful form response are therefore different evidence from an email arriving.
If notifications are required, use an operator-authorized test inbox, review who can access settings and backups, and test the chosen SMTP provider on the deployed runtime. The README's planned Resend path does not prove Resend is the current implementation. Provider charges and domain costs belong in a separate budget.
Estimate quotas from measured operations
Workers Free currently allows 100,000 requests per day across the account and 10 ms CPU per invocation. D1 Free allows 5 million rows read per day, 100,000 rows written per day and 5 GB total storage. Dashboard reads, authentication, migrations and notifications can use resources beyond the single submission insert. Measure a representative workload before translating request limits into a submission capacity claim.
Complete a reversible form pilot
- Use separate resources, synthetic accounts and a non-critical test form.
- Test HTML and JSON submissions, missing form IDs, invalid payloads and redirects.
- Verify dashboard access, exports and cross-account isolation; assess bot traffic and abuse handling before public exposure.
- If required, test actual notification receipt and an observable failure case.
- Keep the old form endpoint available for rollback while checking the new route.
Compare the FormZero workflow, Formspree plans and other alternatives before cutover. Source review and the author's real dashboard image support evaluation; they do not certify a fresh deployment or production readiness.
Common questions
Do I need KV or R2 for the reviewed FormZero deployment?
Its pinned Wrangler configuration declares a Worker with one D1 binding named DB. It does not declare KV, R2, Queues or an email provider binding. An optional SMTP service is configured separately in application settings.
Does this guide prove a working free deployment?
No. It reviews pinned configuration and runtime source and provides a pilot checklist. Installation, delivery, security and workload capacity still need verification in the operator's account.
Sources and review
- FormZero pinned deployment configuration ↗
- FormZero build, remote migration and deployment scripts ↗
- FormZero Worker request handler ↗
- FormZero submission route and optional notification call ↗
- FormZero SMTP helper ↗
- FormZero SMTP settings migration ↗
- Cloudflare Workers pricing ↗
- Cloudflare D1 pricing ↗
Recommendations are Cloudsteading’s editorial assessment. Repository review establishes documented capabilities; it does not prove a fresh deployment or complete feature parity. Prices and platform limits can change.