FormFlow vs Formspree
Developer-friendly React hooks vs HTML-only forms. Both provide backend, but FormFlow integrates better with React apps.
Key Differences
1. React Integration: FormFlow is built for React with hooks API. Formspree is HTML-first.
2. Developer Experience: FormFlow uses modern patterns (react-hook-form). Formspree uses HTML forms.
3. Validation: FormFlow has built-in client-side validation. Formspree is server-only.
4. UI Library Support: FormFlow works seamlessly with shadcn/ui, Material-UI, etc. Formspree requires custom integration.
Code Comparison
Formspree (HTML Forms)
function ContactForm() {
return (
<form
action="https://formspree.io/f/yourFormId"
method="POST"
>
<input
type="email"
name="email"
required
/>
<input
type="text"
name="name"
required
/>
<button type="submit">
Submit
</button>
</form>
);
}
// Limitations:
// ❌ No React state management
// ❌ No client-side validation
// ❌ Page refresh on submit
// ❌ Hard to use with UI librariesFormFlow (React Hooks)
import { useFormFlow } from '@formflow.sh/react';
import { Input } from '@/components/ui/input';
function ContactForm() {
const { register, handleSubmit, formState } =
useFormFlow({
apiKey: process.env.NEXT_PUBLIC_FORMFLOW_API_KEY,
onSuccess: () => alert('Sent!'),
});
return (
<form onSubmit={handleSubmit}>
<Input {...register('email')} type="email" />
<Input {...register('name')} />
<button type="submit">
Submit
</button>
</form>
);
}
// Benefits:
// ✅ React state management
// ✅ Client-side validation
// ✅ No page refresh (AJAX)
// ✅ Works with any UI libraryFeature Comparison
| Feature | FormFlow | Formspree |
|---|---|---|
| React hooks API | ✓ | ✗ |
| Client-side validation | ✓ | ✗ (server only) |
| AJAX submission (no page refresh) | ✓ | ✗ (page refresh) |
| Works with shadcn/ui, MUI | ✓ | Limited |
| TypeScript support | ✓ | ✗ |
| Form state management | ✓ | ✗ |
| Loading states | ✓ | Manual |
| Backend submission | ✓ | ✓ |
| Email notifications | ✓ | ✓ |
| Spam protection | ✓ | ✓ |
| Free tier | 50/month | 50/month |
User Experience
Formspree
- ❌ Page refreshes on submit
- ❌ Lose form state on error
- ❌ No instant validation feedback
- ❌ Generic HTML form experience
FormFlow
- ✓ No page refresh (AJAX)
- ✓ Form state preserved
- ✓ Instant validation feedback
- ✓ Modern React SPA experience
Developer Experience
Working with UI Libraries
Formspree with shadcn/ui
// Doesn't work out of the box
// Need custom integration
<form action="..." method="POST">
<Input name="email" />
{/* Need to manage state manually */}
</form>FormFlow with shadcn/ui
// Works seamlessly
const { register } = useFormFlow({...});
<form onSubmit={handleSubmit}>
<Input {...register('email')} />
</form>Validation
Formspree
Server-side only. Users submit, wait, then see errors.
// Only HTML validation
<input type="email" required />
// Errors shown after submitFormFlow
Client-side + server-side. Instant feedback.
<Input {...register('email', {
required: 'Email required',
pattern: /^[A-Z0-9._%+-]+@.../
})} />
// Errors shown instantlyUse Formspree when:
- ✓ You're building static HTML sites
- ✓ You don't use React
- ✓ You need the simplest possible solution
- ✓ Page refresh is acceptable
Use FormFlow when:
- ✓ You're building a React app
- ✓ You want modern SPA experience
- ✓ You use UI libraries (shadcn, MUI)
- ✓ You need client-side validation
Pricing
FormFlow
Free
50 submissions/month
- ✓ All features included
- ✓ No credit card required
- ✓ Upgrade for more submissions
Formspree
Free
50 submissions/month
- ✓ Basic features
- ✓ No credit card required
- ✓ Upgrade for more submissions
Similar pricing, but FormFlow provides better React integration
Migrating from Formspree
Switch from Formspree to FormFlow for better React integration:
Before (Formspree)
<form
action="https://formspree.io/f/xxx"
method="POST"
>
<input
type="email"
name="email"
required
/>
<button type="submit">
Submit
</button>
</form>After (FormFlow)
const { register, handleSubmit } =
useFormFlow({
apiKey: 'your-api-key'
});
<form onSubmit={handleSubmit}>
<Input
{...register('email')}
type="email"
/>
<button type="submit">
Submit
</button>
</form>