Point any HTML form at one endpoint. 500 free submissions — no card, no time limit — and unlimited forms.
Create free accountEmailJS made "send email from a static site without a backend" easy, and it is still a solid tool for that job. But a contact form usually needs more than one email: a record of every submission, spam filtering, and a way to export or forward leads. A form backend like splitforms covers all of that from a single form action URL, with no email-service credentials or SDK in your frontend. Here is how the two approaches compare and which alternatives are worth a look.
A form that just works — no SMTP config
Point any HTML form at splitforms. Accepted submissions are saved to the dashboard before owner notification email is attempted; delivery varies by provider and recipient settings.
What happens next ⚡
- 📥Submission received — stored in your searchable dashboard
- 📧Email notification — delivered to your inbox instantly
- 🛡️Spam filtered — rule-based content filter + honeypot, no CAPTCHA
- 🔗Webhook fired — optional: forward to Slack, Discord, Sheets
- ↩️User redirected — to your thank-you page
500 free submissions total · No credit card
How does EmailJS work, and where does it fall short?
EmailJS connects your frontend form to an email service you link in its dashboard (Gmail, Outlook, SendGrid and others). You install the @emailjs/browser package, configure a service ID, template ID and public key, and the SDK sends each form as an email through that service.
That works well for sending an email. The friction shows up when you treat it as a contact form backend:
- You maintain the email connection. EmailJS sends through the service you connect. If that connection is revoked or its credentials change, sends fail until you reconnect it.
- Sent emails, not a submissions inbox. EmailJS keeps a send history (7 days on Free, 30 days on paid plans) rather than a searchable submissions database. If an email is lost or filtered, the record of the lead ages out of that window.
- Spam controls guard the template, not the content. EmailJS documents IP-based rate limits, a domain allowlist on paid plans, reCAPTCHA v2 (off until you enable it per template) and SDK options such as
blockHeadlessandlimitRate. The docs describe no content-based spam scoring, honeypot field or spam folder. - 200 requests a month on Free. The free plan also includes 2 email templates and requests up to 50 KB. splitforms gives 500 free submissions with no time limit.
- Templates live in the EmailJS dashboard. Every message is shaped by a template with variable placeholders, so a new form field means a template edit as well as a code change.
What does a form backend like splitforms do differently?
splitforms flips the model. Instead of sending through your email service, it receives the submission on its own server, stores it, filters it and then emails you.
- Zero email config. No SMTP credentials to manage. No service IDs, template IDs or public keys. One access key and one endpoint.
- Submissions are stored. Every submission lands in a searchable dashboard with timestamps and IP, with no automatic expiry on any plan. Export to CSV on paid plans.
- Smart spam filtering built in. Each submission gets automatic spam scoring on the server, alongside honeypot and time-trap checks, before it reaches your inbox.
- Webhooks on Pro ($5/month). Forward submissions to Slack, Discord, Notion, Zapier or your own API endpoint.
- Autoresponders on paid plans. Send a confirmation email back to the person who filled the form, with no template engine to learn.
EmailJS vs splitforms: how do they compare?
| Feature | EmailJS | splitforms |
|---|---|---|
| Free plan | 200 requests/month, 2 templates | 500 submissions total, no time limit |
| Submission storage | Email history: 7 days Free, 30 days paid; readable via the /history API | Searchable dashboard, no automatic expiry on any plan |
| Spam filtering | IP rate limits, domain allowlist (paid), reCAPTCHA v2; no content scoring documented | Automatic spam scoring built in |
| Email credentials | You connect a service (Gmail, Outlook, etc.) | Handled; optional custom SMTP on paid plans |
| Webhooks | None documented | On Pro ($5/month) and Annual |
| Autoresponders | Via an auto-reply template | On paid plans |
| Paid plan | Personal $9/month for 2,000 requests | Pro $5/month for 5,000 submissions; Annual $49/year for 15,000/month |
| Setup | SDK install + service/template config | Add action URL + access key |
Other EmailJS alternatives
A form backend is not the only route. Depending on how much you want to own:
- Formspree: a hosted form backend with 50 submissions a month free.
- Web3Forms: an access-key form endpoint with 250 submissions a month free.
- FormSubmit: free and unlimited, but email-only, with no dashboard.
- Resend plus your own serverless function: full control, but you write, host and secure the route yourself.
If you want to understand the trade-offs before picking one, our guide to a contact form without a backend walks through each approach.
What does the code look like?
EmailJS requires a client SDK and configuration objects:
// EmailJS — requires SDK + config
import emailjs from '@emailjs/browser';
emailjs.sendForm('SERVICE_ID', 'TEMPLATE_ID', formRef.current, {
publicKey: 'YOUR_PUBLIC_KEY',
})
.then(() => alert('Sent!'))
.catch((err) => alert('Failed: ' + err.text));splitforms is just HTML. No SDK, no build step, no client-side JavaScript:
<!-- splitforms — plain HTML, no SDK needed -->
<form action="https://splitforms.com/api/submit" method="POST">
<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>That's it. No npm install, no service ID, no template variable mapping. The form works on any static host (GitHub Pages, Netlify, Vercel, S3) with zero JavaScript.
When does EmailJS still make sense?
EmailJS isn't bad software. It's a good choice if:
- You already have a configured email service (SendGrid, Mailgun, Postmark) and want to keep sending through it directly.
- You need to send transactional emails from the browser (not just form submissions) and EmailJS is your transport layer.
- You only need an email sent, and you don't need a stored record of each submission.
For contact forms, lead capture and signups on static sites, a form backend gives you storage, spam filtering and exports with less configuration, and splitforms Pro is $5/month.
How do you switch from EmailJS? (5 minutes)
- Create a free account at splitforms.com/login
- Copy your access key from the dashboard
- Remove the
@emailjs/browserSDK calls from your form - Set your form's
actiontohttps://splitforms.com/api/submit - Add
<input type="hidden" name="access_key" value="YOUR_KEY"> - Deploy. Test. Done.
In React, keep your component and swap the SDK call for a fetch. Your field names can stay the same:
// React — replaces emailjs.sendForm(...)
async function onSubmit(e) {
e.preventDefault();
const res = await fetch('https://splitforms.com/api/submit', {
method: 'POST',
body: new FormData(e.currentTarget), // includes the hidden access_key input
headers: { Accept: 'application/json' },
});
alert(res.ok ? 'Sent!' : 'Something went wrong');
}For a full component with loading and error states, see the React form guide.
FAQ
Is EmailJS free?
Yes. EmailJS Free includes 200 requests a month, 2 email templates, requests up to 50 KB and 7 days of email history. Personal is $9/month for 2,000 requests.
Is it safe to put my EmailJS public key in frontend code?
The public key is designed to be public, but anyone who copies it can send requests against your monthly quota. EmailJS documents IP-based rate limits, a domain allowlist (Personal and up) and reCAPTCHA v2 per template, so switch those on for a public form. A server-side form backend avoids putting an email-sending key in the browser at all.
EmailJS vs Formspree: which is better for a contact form?
EmailJS sends an email from the browser through your own email service using its SDK and templates. Formspree and other form backends accept a plain HTML POST, then store, filter and forward submissions. Pick EmailJS if you only need an email sent, and a form backend if you want an inbox, spam filtering and exports.
Does EmailJS store form submissions?
Only as a send log. EmailJS keeps email history for 7 days on Free and 30 days on paid plans, viewable in its dashboard and readable through its /history REST API with your private key, and templates can save senders as contacts that you can export as CSV. It is not a searchable submissions inbox. A form backend such as splitforms stores every submission in a dashboard, with no automatic expiry on any plan.
Can I keep my React code when switching from EmailJS?
Yes. Replace emailjs.sendForm(...) with fetch('https://splitforms.com/api/submit', { method: 'POST', body: new FormData(form), headers: { Accept: 'application/json' } }) and add a hidden access_key field. Your field names can stay the same.
What's the cheapest EmailJS alternative?
Free options: FormSubmit (unlimited, email-only) and Web3Forms (250 a month). Paid: splitforms Pro is $5/month for 5,000 submissions a month (or $49/year for 15,000 a month on Annual), versus EmailJS Personal at $9/month for 2,000 requests.
Is splitforms really free?
Yes. The free plan includes 500 submissions with no card and no time limit, unlimited forms, email notifications, smart spam filtering and a searchable dashboard, with no automatic expiry on any plan. The 500 is a total rather than a monthly allowance; if you need a monthly allowance, Pro is $5/month for 5,000 submissions a month and Annual is $49/year for 15,000 a month.
Do I need to connect my own email service with splitforms?
No. EmailJS sends through an email service you connect and keep connected, such as Gmail or Outlook. splitforms sends the notification email itself: point your form at https://splitforms.com/api/submit and accepted submissions are saved to the dashboard before the owner notification email is attempted; delivery time and inbox placement depend on provider and recipient settings.
Can I still use my own SMTP with splitforms?
Yes. On paid plans you can configure custom SMTP (Gmail App Password, AWS SES, Postmark, or your own server) for outbound delivery. That gives you the sender control EmailJS offers without wiring an SDK into your frontend.
Does splitforms work with React, Vue, and plain HTML?
Yes. splitforms is framework-agnostic. Any HTML form that can POST works: React, Vue, Svelte, Astro, Next.js, Gatsby, plain HTML or a no-framework static site. Set the action URL and add your access key.
What about rate limits and reliability?
The free plan covers 500 accepted submissions in total and is also subject to anti-abuse rate limits. Pro ($5/month) covers 5,000 submissions a month, and Annual ($49/year) covers 15,000 a month.