DEV Community

Cover image for React Form Backends Compared: Serverless Functions vs. Form-as-a-Service

React Form Backends Compared: Serverless Functions vs. Form-as-a-Service

React Form Backends Compared: Serverless Functions vs. Form-as-a-Service

React makes building a form straightforward. What happens after onSubmit is a different question: you still need somewhere to validate, process, store, or forward the submission. Two common approaches are writing a serverless function yourself or using a hosted form backend such as onsubmit.dev (form backend). This article compares the two, using Vercel/Netlify-style functions for the DIY approach and onsubmit.dev with its React integration as the managed example.

The basic problem

Imagine a typical contact form:

function ContactForm() {
  return (
    <form>
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button type="submit">Send</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

The React component is only the UI. A real application usually needs backend behavior too:

  • accepting the HTTP request
  • validating and sanitizing input
  • handling errors
  • preventing abuse or spam
  • delivering or storing the submission
  • keeping credentials and other secrets off the client

There are two broad ways to get that backend.

Option 1: Build a serverless function

With platforms such as Vercel and Netlify, you can create an HTTP function alongside your application and have your React form submit to it.

Conceptually, the architecture looks like this:

React form
    |
    v
Your serverless function
    |
    +--> validation
    +--> email provider
    +--> database
    +--> other services
Enter fullscreen mode Exit fullscreen mode

The main advantage is control.

Your function owns the request lifecycle, so you decide precisely how data is validated, transformed, authenticated, stored, and forwarded. If a submission needs to update PostgreSQL, call an internal API, enqueue a job, and return application-specific data, a custom backend is usually the natural solution.

Serverless functions can also reduce product-level vendor lock-in. Although platforms have their own deployment conventions, HTTP handlers and their business logic are generally portable with some work.

The trade-off is that "just one endpoint" can become infrastructure you have to maintain.

Once a public form ships, you may need to think about spam protection, rate limits, malformed requests, retries, monitoring, email delivery, secrets, and platform limits. None of those problems is necessarily difficult by itself, but they consume development time.

Option 2: Use a form backend service

A form-as-a-service product moves that generic infrastructure out of your application:

React form
    |
    v
Hosted form backend
    |
    +--> submission handling
    +--> form workflow
Enter fullscreen mode Exit fullscreen mode

This approach is particularly appealing for contact forms, feedback forms, waitlists, and other forms where building a custom API isn't part of the application's core value.

As a concrete example, onsubmit.dev (form backend) exposes form endpoints and provides framework integrations, including the react-onsubmit package. Its documentation also covers integrations for Next.js, Astro, and Vue.

Rather than reproducing integration code that can become stale as the package API evolves, use the current package example from the service's docs when implementing it. The important architectural difference is that submission processing belongs to the hosted service rather than to a function in your application.

That means fewer backend components for your team to write and operate.

Where serverless functions win

A DIY function is the stronger option when form submission is really an application operation disguised as a form.

Consider a checkout, account workflow, authenticated settings page, or an internal tool that modifies several domain objects. These flows often need custom authorization, database transactions, application-specific validation, or calls into private services.

A serverless function gives you that flexibility.

It can also make sense if your organization already has mature backend infrastructure. If logging, rate limiting, deployment, alerting, and email are solved problems internally, adding one more endpoint might be cheaper than introducing another service.

Where a hosted form backend wins

The biggest advantage is development time.

For a marketing site with one contact form, creating and maintaining a dedicated function may add little business value. A managed endpoint lets the frontend remain focused on collecting the data while somebody else operates the submission infrastructure.

This is especially useful for static sites. One of the attractions of React-based static deployments is that they can have very little infrastructure. Adding a function solely because a contact page needs to send three fields partially gives up that simplicity.

onsubmit.dev (form backend) and similar services therefore fit best when the form workflow is relatively generic and you value a smaller operational surface.

The trade-offs aren't only technical

The managed approach introduces vendor dependency.

Your forms now rely on another company's API, availability, pricing, limits, and feature set. Migrating later means changing the integration and potentially replacing functionality you previously received from the service.

A DIY serverless function has dependencies too: your hosting provider, email service, database, CAPTCHA provider, and other infrastructure may all be vendors. The difference is that you control the glue connecting them.

There is also a cost comparison that isn't obvious from monthly pricing alone.

A serverless function can be extremely cheap to execute, particularly at low volume. But engineering and maintenance time have a cost. A hosted service may have a higher direct subscription cost while requiring less engineering work.

So the useful calculation is closer to:

total cost = service/infrastructure cost + engineering time + maintenance
Enter fullscreen mode Exit fullscreen mode

rather than simply comparing request prices.

What about security?

Neither architecture automatically makes a public form secure.

Client-side React validation is useful UX, but requests can bypass it entirely. Anything that matters must be enforced by the system receiving the request.

With a serverless function, that responsibility is primarily yours. With a form backend, you are delegating some of it to the provider, which means evaluating its security model and deciding whether it is appropriate for the data you're collecting.

For sensitive or highly regulated data, that evaluation can outweigh implementation convenience.

A practical decision rule

For many React projects, the choice can be reduced to the amount of custom backend behavior required.

Use a serverless function when you need substantial business logic, custom authentication or authorization, direct control over storage, unusual integrations, or infrastructure portability.

Use form-as-a-service when the workflow is a conventional contact, feedback, signup, or similar form; getting it shipped quickly matters; and operating another endpoint isn't valuable to your team.

There's also no requirement to standardize the entire application on one approach. A company can use a hosted form backend for its public marketing forms while keeping product workflows behind its own APIs.

Conclusion

Serverless functions and hosted form backends solve overlapping problems at different layers.

Vercel or Netlify functions give React developers maximum control at the cost of owning more code and infrastructure. A hosted solution such as onsubmit.dev (form backend), including its react-onsubmit integration, trades some of that control and portability for less backend work.

For a three-field contact form, that can be an excellent trade. For a form triggering core application logic, writing the endpoint yourself will often age better.

The important question isn't whether a React app can implement the backend. It almost certainly can. It's whether maintaining that backend is where you want to spend your development time.

Top comments (0)