Limited-time offer The first 2,000 users get 10,000 emails/month free for a year 1,995 of 2,000 spots left Claim yours

Guides

How to send email from JavaScript (no backend)

There’s no sendEmail() in the browser. Here’s why, what people try instead, and a safe way to do it with one fetch() call.

Last updated October 26, 2026

Why JavaScript in the browser can’t send email

Email travels over SMTP, a protocol that runs on raw TCP connections to ports like 465 and 587. Browsers only let pages make HTTP and WebSocket requests, so front-end JavaScript can’t open an SMTP connection at all. Something on a server has to receive your request over HTTPS and talk SMTP on your behalf.

Your options

ApproachGoodNot so good
mailto: linkZero setupOpens the visitor’s mail app instead of sending. Many visitors have none set up, and you can’t control what arrives.
Browser “SMTP” librariesLooks like one function callThey relay through a third-party server, and the page needs your SMTP login (or a token tied to it). Anyone who opens DevTools can copy it and send as you, to anyone.
Your own serverless functionFull controlYou write, deploy and secure backend code, store SMTP secrets on the platform, and build your own spam and rate limits.
FormSMTPOne fetch(), sent through your own SMTP, no password in the pageYou need an email account with SMTP access (nearly all have one).

Never put an SMTP password in front-end code, even “obfuscated”. Your page source is public, and a leaked mailbox password is far worse than a leaked form key.

How it works

Your SMTP login stays encrypted in FormSMTP. The page only holds a project key, which you lock to your website, your own inbox and an hourly limit. Your script posts to FormSMTP over HTTPS; FormSMTP checks the request and sends through your SMTP server, so the email comes from your own address.

1Create a FormSMTP project

Sign up free and add a project. Pick your email provider so the SMTP host and port fill in, enter your login, and click Test connection. Not sure which provider? Your existing mailbox works: see the Gmail or Zoho guides.

2Lock the project to your site

In Settings → Security, set Allowed websites to https://yoursite.com and Allowed recipients to your own address. Now the key in your page can only email you, only from your site, and only up to your hourly limit.

3Send from a form

Plain HTML with a little JavaScript for an inline result. Without JavaScript, the form still works and shows a thank-you page.

html
<form id="contact" action="https://app.formsmtp.com/api/v1/form/YOUR_API_KEY" method="POST">
  <input name="name" placeholder="Name" required>
  <input name="email" type="email" placeholder="Email" required>
  <textarea name="message" placeholder="Message" required></textarea>
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
  <button type="submit">Send</button>
  <p id="status" role="status"></p>
</form>

<script>
  const form = document.getElementById("contact");
  const status = document.getElementById("status");
  const button = form.querySelector("button");

  form.addEventListener("submit", async (e) => {
    e.preventDefault();
    button.disabled = true;
    status.textContent = "Sending…";
    try {
      const res = await fetch(form.action, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new URLSearchParams(new FormData(form)),
      });
      const data = await res.json();
      if (!data.success) throw new Error(data.error);
      form.reset();
      status.textContent = "Thanks! Your message was sent.";
    } catch (err) {
      status.textContent = "Sorry, that didn't work: " + err.message;
    } finally {
      button.disabled = false;
    }
  });
</script>

4Or send from any JavaScript

No form on the page? Post JSON to the same endpoint from anywhere in your code: a chat widget, a quiz result, a “notify me” button. Every field that doesn’t start with an underscore ends up in the email.

js
async function sendEmail(fields) {
  const res = await fetch("https://app.formsmtp.com/api/v1/form/YOUR_API_KEY", {
    method: "POST",
    headers: { "Content-Type": "application/json", Accept: "application/json" },
    body: JSON.stringify(fields),
  });
  const data = await res.json();
  if (!data.success) throw new Error(data.error);
  return data.messageId;
}

await sendEmail({
  _subject: "New quote request",
  email: "ana@example.com",   // becomes the reply-to address
  plan: "Team",
  seats: 12,
});

The email goes to the address in Allowed recipients (or the project’s From address), with the visitor’s email as reply-to, so you can answer straight from your inbox.

Sending from Node.js or a server

On a server, the key stays secret, so you can use the full send API: any recipient you allow, HTML, templates, cc/bcc and attachments.

js
const res = await fetch("https://app.formsmtp.com/api/v1/send", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FORMSMTP_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "customer@example.com",
    subject: "Your order has shipped",
    html: "<p>Good news: it's on the way.</p>",
  }),
});
const data = await res.json(); // { success: true, messageId } or { success: false, error }

Handling errors

Every response is JSON with success, and an error message when it fails. A 429 means the project’s hourly limit was reached (check the Retry-After header); a 502 means your SMTP server refused the message, and the error says why. The full list is in the docs.

FAQ

Can JavaScript send email without a server?

Not by itself. Browsers can’t open SMTP connections, so a service has to receive the request over HTTPS and send the email. FormSMTP does that through your own SMTP account, so you don’t run a server.

Is it safe to use my Gmail password in JavaScript?

No. Anything in front-end code is visible to every visitor. Keep the SMTP login on a server; with FormSMTP it’s stored encrypted and the page only holds a key that can email you and nobody else.

Can I send attachments from the browser?

Not through the form endpoint, which doesn’t accept file uploads. The send API accepts base64 attachments, but call it from a server so your key stays private.

Why did my message land in spam?

Usually the From address and the SMTP account don’t match, or the domain has no SPF/DKIM records. Send from the address you log in with, and check the Deliverability panel in FormSMTP’s Settings.

More guides

Get a Founding Pass

10,000 emails a month, free for your first year. Pass No. 0006 is next: 1,995 of 2,000 left, no card.