Switching from EmailJS, one import at a time
EmailJS invented sending email straight from the browser, and Email Fast started life as an answer to it — same call signatures, different answer to the question of what a leaked public key can do.
Facts verified 2026-08-29 — corrections: hello@emailfast.dev
The whole code change
- import emailjs from "@emailjs/browser";
+ import emailjs from "@email-fast/browser";
emailjs.init({ publicKey: "ef_pub_..." });
await emailjs.send("default", "template_contact", {
name: "Ada",
message: "Hello from the contact form",
});sendForm keeps its signature too, and the endpoints behind the SDK accept the EmailJS request body — user_id, service_id, template_id, template_params — so even code you can't touch keeps working against a new base URL. The structural difference is what a stolen key can do: a browser SDK with EmailJS-compatible endpoints — the recipient always comes from the server-stored template, never from the request, so a public key in your frontend can't be abused to spam arbitrary addresses.
How long it actually takes
| What you're moving | The work | Time |
|---|---|---|
| The browser integration | Swap the npm package, keep your call sites | Minutes |
| Templates | Re-created by hand — no EmailJS importer exists | About ten minutes each; most setups have one or two |
| Testing | Point the same code at a sandbox key | Under an hour, end to end |
| A server-side lane (optional) | Send the same stored template over the REST API | An afternoon, when you're ready |
The realistic total for a contact-form integration: one sitting. Prove it without sending anything real first — sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves.
Templates carry the addressing
An EmailJS template holds To, CC, BCC, Reply-To, subject, and body. That model carries over with one deliberate exception: {{variables}} work in every field except To — the To address is fixed when the template is created, because on the browser lane the recipient never comes from the request. And a variable filled into CC or BCC can add at most the one address its slot was written for: a value that tries to carry a comma, a second address, or a header break is dropped, not split into extra recipients. The walkthrough, including a template that CCs your support team: migrate from EmailJS.
What EmailJS publishes at your volume
| Monthly emails | Price / month | Published as |
|---|---|---|
| 10,000 | $30 | Professional (10k quota) |
| 50,000 | $80 | Business (50k quota) |
| 100,000 | $140 | Business (100k quota) |
| 200,000 | $200 | Business (200k quota, largest self-serve tier) |
| 500,000 | not published | Professional / Business — NOT OFFERED - largest self-serve quota is 200,000/mo at $200; beyond that is 'Contact us' |
Detail: Prices from the in-card quota sliders, monthly billing (yearly is 20% off). Free: 200 requests/mo. Personal: $9/mo for 2,000. Professional: $15/mo at 5,000, $30/mo at 10,000. Business: $40/mo at 25,000, $80/mo at 50,000, $140/mo at 100,000, $200/mo at 200,000. No overage billing - requests beyond quota are simply not processed (hard stop). No public tier above 200,000/mo ('Contact us'). A 'request' is one email send.
Not published / not verified: Any pricing above 200,000 requests/mo (not offered self-serve).
Figures verified 2026-08-29 on the EmailJS pricing page, promo and intro discounts excluded — method and corrections via the claims methodology.
The model difference worth pulling out of the fine print: EmailJS stops processing requests beyond your quota. Here, paid plans bill overage per 1,000 past the monthly cap, the Free plan stops at its cap, and daily sending ceilings that rise with account history apply on every plan. Price your own volume: 10,000 sends/month or 100,000.
Where Email Fast stands
| Plan | Price / month | Emails included | Overage per 1,000 |
|---|---|---|---|
| Free | $0 | 2,500 | — |
| Starter | $9.90 | 20,000 | $0.90 |
| Creator | $39 | 100,000 | $0.65 |
| Growth | $79 | 300,000 | $0.55 |
| Scale | $249 | 1,500,000 | $0.35 |
Our stake, declared: we make Email Fast, and these are the launch prices already published on our pricing page — during early access they may be refined before general availability, and self-serve checkout opens at GA. Contacts and subscribers are never billed, at any list size.
Where EmailJS wins
From our own pricing survey, their side stated plainly — Sends email straight from client-side JavaScript with no backend at all - the fastest possible setup for contact forms and small apps, with a template editor built in.
Honest additions: if your contact form already works, even a small switch has a cost, and no unmet need means no reason to move. EmailJS is the original, single-purpose tool in this category — smaller surface, nothing new to learn. The full comparison: EmailJS vs Email Fast.
Next
- The step-by-step migration guide
- Frontend email, done safely — how the key model works
- Suspended by your current platform? Read that first.
- Apply for early access — live sending starts by application
EmailJS is a trademark of its owner; Email Fast is not affiliated with or endorsed by them. EmailJS facts were verified on their public pages on the dates shown — corrections: hello@emailfast.dev.
Questions, answered plainly
Is the browser API really the same?
The package keeps the init, send, and sendForm signatures, and the endpoints accept the EmailJS request body — user_id, service_id, template_id, template_params — unchanged. What changes is the security model: a browser SDK with EmailJS-compatible endpoints — the recipient always comes from the server-stored template, never from the request, so a public key in your frontend can't be abused to spam arbitrary addresses.
Do my EmailJS templates transfer automatically?
No — there is no EmailJS template importer. You re-create each template in the dashboard (fields for To, CC, BCC, Reply-To, subject, and body, with variables in every field except To — the To address is fixed when the template is created, because on the browser lane the recipient never comes from the request) or over POST /v1/templates. A typical contact-form setup is one or two templates — call it ten minutes each.
What happens when I outgrow the browser?
That's the part EmailJS never offered: the same stored template can be sent server-side over the REST API with a secret key choosing the recipient — one template, two callers. And when you add a backend, SDKs for the browser (EmailJS-compatible), Node.js, Python, PHP, Go, and Ruby, plus a zero-dependency CLI and a published OpenAPI specification.
What happens if I go over my monthly volume?
On EmailJS's published model, requests beyond your plan's quota are not processed. Here it depends on the plan: paid plans keep sending past the monthly cap and bill the extra at their published per-1,000 overage rate, while the Free plan stops at its cap. Separate from billing, every account has daily sending ceilings that rise as it builds history. The table on this page is the launch pricing from our pricing page.