Skip to content

Migrating from EmailJS

Frontmail was designed so that moving from EmailJS takes minutes: the browser SDK has the same function signatures, the REST API accepts the same fields, and the template syntax is compatible for simple templates.

1. Create your organization and connect the service

Section titled “1. Create your organization and connect the service”

Sign up at app.frontmail.dev and connect the same email provider you use in EmailJS (see Services). If you used a Gmail or Outlook service, reconnect it via OAuth; for SMTP or API providers, enter the same credentials.

Create a template for each EmailJS template. Copy subject, To, From, Reply-To and the content. Then click Detect parameters and set types and required flags – see template syntax below for differences.

EmailJS Frontmail Where to find it
Public Key (user_id) Public key pk_… Security → Public key
Private Key (accessToken) Private key sk_… – server only Security → Private keys (shown once)
Service ID Service ID svc_… Email services
Template ID Template ID tpl_… Templates
Domain allowlist Allowed websites Security → Allowed websites
reCAPTCHA Cloudflare Turnstile with your own free widget Keys in Security → Bot protection (Turnstile), per template Settings → Protection → Require CAPTCHA (Turnstile)
import emailjs from '@emailjs/browser';
import emailjs from '@frontmail/emailjs-compat';

Your emailjs.init(), emailjs.send() and emailjs.sendForm() calls keep working – only the IDs and the key change. See EmailJS compatibility.

Using the CDN script? Replace the EmailJS <script> with the compat build, which exposes the same emailjs global, so your calls stay unchanged:

<script
src="https://cdn.jsdelivr.net/npm/@frontmail/emailjs-compat@0.1.0/dist/emailjs-compat.umd.js"
integrity="sha384-RH+fuNzBqTKgxDJBHRmWfOn37fs33L+Or1ujDV7wThynx9FxD9uPptLu80LpCrEc"
crossorigin="anonymous"></script>

Pin the exact version and keep the integrity attribute – see Pin the version for where to find the hash of newer releases.

Alternatively, load the native SDK (@frontmail/browser, same pinning) and rename emailjs. calls to frontmail. – the arguments are the same, but the promise resolves with status: 'queued' or 'held' instead of 200.

Calling the REST API directly? Change the host to https://api.frontmail.dev. The paths /api/v1.0/email/send and /api/v1.0/email/send-form and the body fields stay the same.

If your templates used reCAPTCHA, remove the reCAPTCHA widget and add Turnstile. Just like with reCAPTCHA, you use keys from your own account: create a free Turnstile widget in Cloudflare, paste its keys into Security → Bot protection (Turnstile) and click Turn on CAPTCHA for all templates; new templates then require it by default. Put the widget with your site key into the form – see Turnstile. The g-recaptcha-response field is not used.

Send a test from the template editor, deploy, and watch History. Keep your EmailJS account until you’ve seen real traffic go through.

@frontmail/browser or a framework SDK gives you typed params, held status, getStatus() and typed errors.

Frontmail uses Handlebars; EmailJS uses a Mustache-like syntax. Common cases:

EmailJS Frontmail Notes
{{name}} {{name}} Same. Always HTML-escaped in Frontmail.
{{{html_content}}} {{html_content}} with param type html Triple braces don’t disable escaping in Frontmail; use the sanitized html type.
{{#if}}-style sections from Mustache {{#name}}…{{/name}} {{#if name}}…{{/if}} Use explicit Handlebars blocks.
Mustache inverted section {{^name}}…{{/name}} {{#unless name}}…{{/unless}}
Lists via sections {{#each items}}…{{/each}} with a list param Define itemFields for validation.
– {{formatDate}}, {{formatMoney}}, {{eq}}… Extra helpers.

Default values set in EmailJS template fields map to the param’s default in Frontmail.

A factual comparison of features relevant for migrating, as of September 2026. Pricing and limits of both services change over time – check the providers’ own pages before deciding.

EmailJS Frontmail
When monthly quota is used up Requests are rejected until the next period or an upgrade Messages are held and sent automatically when credits are added; optional overdraft and auto top-up
Prepaid credit packs with validity Not offered 5k / 25k / 100k packs valid 3–12 months, on every plan
REST API rate limit 1 request per second 2–50 requests per second depending on plan, plus /v1/send-batch
Template language Variables with simple sections Handlebars with conditions, loops, helpers and typed, validated params
CAPTCHA reCAPTCHA v2 Cloudflare Turnstile, on for all templates in one click
Provider failover Not offered Fallback service per template, daily health checks
Delivery tracking Not offered Delivered / bounced / complained / opened / clicked via provider webhooks
SDK retries and idempotency Not documented Automatic retries with idempotency keys
Framework SDKs Browser SDK, React Native SDK Browser, React, React Native, Vue, Svelte, Node, EmailJS-compatible

If you spot an outdated statement here, please tell us at support@frontmail.dev and we’ll fix it.