# Switching from EmailJS, one import at a time

> Switch from EmailJS with a one-package swap: the same init, send, and sendForm calls, a hardened public-key model, honest timelines, and dated pricing.

Canonical: https://emailfast.dev/alternatives/emailjs

## The whole code change

```diff
- 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](/migrate/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](https://www.emailjs.com/pricing/), promo and intro discounts excluded — method and corrections via the [claims methodology](/legal/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](/compare/pricing-calculator?sends=10000&contacts=1000) or
[100,000](/compare/pricing-calculator?sends=100000&contacts=10000).

## 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](/pricing) — 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](/compare/emailjs-alternative).

## Next

- [The step-by-step migration guide](/migrate/emailjs)
- [Frontend email, done safely](/features/frontend) — how the key model works
- [Suspended by your current platform?](/alternatives/suspended) Read that first.
- [Apply for early access](/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](/contact).*

## 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 .
