Quickstart: Browser (frontend-only)
A contact form that emails you, with no backend — and a public key designed to be safe in view-source.
Facts verified 2026-07-17 — corrections: hello@emailfast.dev
1. Install and send
npm install @email-fast/browserimport emailjs from "@email-fast/browser";
emailjs.init({ publicKey: "ef_pub_..." }); // safe to ship — see below
await emailjs.send("default", "template_contact", {
name: "Ada",
message: "Interested in the ledger product.",
reply_to: "ada@example.com",
});Or bind a whole form in one call — field names become template params:
document.querySelector("#contact").addEventListener("submit", (e) => {
e.preventDefault();
emailjs.sendForm("default", "template_contact", e.target);
});The API is EmailJS-compatible (same init/send/sendForm signatures), so migrating from EmailJS is an import swap.
2. Why a public key in your HTML is safe here
An ef_pub_ key is visible to every visitor, so the design assumes it is stolen: 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.
That one rule — recipient from the template, never from the request — is what makes the key shippable. template_params fills placeholders in your template addressed to your inbox; there is no parameter that redirects mail. Around it:
- Origin allowlist. In the dashboard, list the origins allowed to use the key (
https://yourdomain.com). Requests from other origins are refused, so a copied key is dead weight on someone else's site. - Typed variable schema. Each template declares its parameters and their types. Unknown keys are stripped, wrong types rejected — a hostile
template_paramscan't inject markup or oversized junk. - Rate caps. Per-key caps bound what a script in a loop can burn.
3. Test without sending anything
Point the template at a sandbox project while you build: sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves. Submit your form, open the capture inbox, and see exactly what would have been delivered.
When you outgrow frontend-only
Server-side sends get the full REST API with explicit idempotency_key support — start with the Node.js quickstart.