Sending email directly from the browser without needing a backend server is now possible using SMTP.js. SMTP.js is a JavaScript SMTP client library that allows you to send mail through client-side JavaScript by wrapping the SMTP protocol.
In this post, we'll cover how to get started with SMTP.js, its features, use cases, and some frequently asked questions on using a JavaScript SMTP library.
Follow this guide to learn How to Scrap LinkedIn Company Data using Voyager Api.
Why Send Email from the Browser?
Here are some reasons you may want to send email directly from the browser without a backend server:
- No server dependencies - You don't need to rely on a server language like PHP or Node.js to send mail. The entire email process can be handled client-side.
- Faster prototyping - You can quickly build and iterate on a contact form or newsletter subscription without needing backend code.
- Reduced server load - Sending mail client-side reduces the load on your servers.
- Increased privacy - Email contents stay isolated in the browser and aren't sent to your servers.
- Offline functionality - Emails can still be drafted and sent when offline or on poor connections. They will queue and send when a connection is re-established.
Limitations of Client-Side Email
There are some limitations to keep in mind:
- No server-side templates - You lose the ability to leverage templating engines like Pug or Handlebars. HTML email needs to be crafted client-side.
- No server-side storage - You won't have a server log of sent mail. Client-side storage like IndexedDB can be used instead.
- Spam prevention - Special care must be taken to prevent spam and abuse without server-side systems like CAPTCHA.
- Email deliverability - Reputation management is harder without consistent IP addresses and server-side software.
So, while SMTP.js removes backend dependencies, some use cases still lend themselves better to server-side email. But for many front-end-focused, privacy-centric, or offline-first applications, SMTP.js can be a great fit.
LinkedIn Voyager API: The Ultimate Developer’s Guide
Getting Started with SMTP.js
SMTP.js can be installed via npm:
npm install smtp.js
Or included directly in the browser from a CDN like unpkg:
<script src="
https://unpkg.com/smtp.js/dist/smtp.min.js"></script>
To send a simple test email:
import smtp from 'smtp.js';
const email = {
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Test email',
text: 'This is a test email sent from the browser'
}
smtp.sendMail(email)
.then(info => console.log(info))
.catch(err => console.error(err))
We provide SMTP credentials and call smtp.sendMail() with the email object containing from, to, subject, and text fields.
The promise resolves with info about the message or rejects any errors.
SMTP Provider Credentials
To send real email, SMTP credentials need to be supplied:
const credentials = {
host: 'smtp.example.com',
port: 465,
secure: true,
auth: {
user: 'username',
pass: 'password'
}
}
smtp.connect(credentials)
.then(info => {
// connected, credentials OK
})
Any SMTP provider can be used, like Gmail, Outlook, or a custom server.
Gmail would look something like:
```javascript">const credentials = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'myaccount@gmail.com',
pass: 'mypassword'
}
}
Now, credentials are supplied to smtp.connect() before sending mail.
<h4>Sending the Message</h4>
With credentials configured, sending an email follows the same pattern:
```javascript">const email = {
// sender/recipient
from: 'sender@example.com',
to: 'recipient@example.com',
// email content
subject: 'Test email',
text: 'Email content here'
}
smtp
.connect(credentials)
.then(() => smtp.sendMail(email))
.then(info => console.log('Email sent!'))
.catch(err => console.error(err))
The message object can also take HTML email content:
const email = {
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'HTML email',
html: '<p>This is an <strong>HTML email</strong></p>'
}
That covers the basics of sending email with SMTP.js! Next we'll look at some more advanced features.
SMTP.js Features
SMTP.js supports several helpful features when sending mail:
- Multiple Recipients
To send to multiple recipients, pass an array of addresses to:
const email = {
to: [
'recipient1@example.com',
'recipient2@example.com'
]
}
CC and BCC fields are also supported:
const email = {
to: 'main@example.com',
cc: 'cc@example.com',
bcc: 'bcc@example.com'
}
- Attachments
To attach files, pass an array of attachments:
const email = {
attachments: [
{filename: 'report.pdf', content: pdfBuffer}
]
}
The content can be a Buffer, ArrayBuffer, Stream, or URL.
- Custom Headers
Additional headers can be added:
const email = {
headers: {
'X-Custom-Header': 'value'
}
}
- Email Queue
To send multiple emails, an internal queue is used:
// add emails to queue
smtp.addMailToQueue(email1);
smtp.addMailToQueue(email2);
// connect and send entire queue
smtp.connect(credentials)
.then(() => smtp.flushQueue())
.catch(err => console.error(err));
This allows sending a batch of emails efficiently.
- Custom SMTP Server
Instead of a major provider, you can connect to a custom SMTP server:
const credentials = {
host: 'mail.yourdomain.com',
port: 587,
secure: false,
auth: {
user: 'username',
pass: 'password'
}
}
Use any self-hosted SMTP server like Postfix, Sendmail, or Exchange.
This covers the main features of SMTP.js! Next we'll look at some good use cases for sending email from the browser.
When to Use SMTP.js
Several types of applications lend themselves well to using SMTP.js for client-side email:
- Contact Forms
A common use case is browser-based contact forms:
const form = document.querySelector('#contact-form');
form.addEventListener('submit', event => {
event.preventDefault();
const email = {
to: 'contact@example.com',
subject: form.subject.value,
text: form.message.value
}
smtp.sendMail(email)
.then(() => form.reset())
.catch(err => console.error(err))
});
No server code is needed!
- Newsletter Signup
For a newsletter signup form, save the email to IndexedDB and queue the confirmation:
form.addEventListener('submit', event => {
event.preventDefault();
const email = form.email.value;
db.users.add({email});
const confirmEmail = {
to: email,
subject: 'Please confirm signup',
text: 'Click here to confirm: https://...'
}
smtp.addMailToQueue(confirmEmail);
smtp.flushQueue();
})
- Online Email Client
SMTP.js allows building a web-based email client or webmail system without servers.
Messages stay local using IndexedDB or other browser storage for the mail client.
- CRM/Support Platforms
In customer management apps, support agents can respond to tickets directly from the browser:
agentForm.addEventListener('submit', event => {
event.preventDefault();
const {recipient, body} = form;
smtp.sendMail({
to: recipient,
text: body
});
});
Again, no server-side code is needed for sending responses.
- Offline Functionality
For offline-first web apps, emails can be queued when offline and sent when a connection is
re-established:
// detect connection state
const isOnline = navigator.onLine;
// queue message
smtp.addMailToQueue(email);
if(isOnline) {
smtp.flushQueue();
} else {
window.addEventListener('online', () => {
smtp.flushQueue();
});
}
So SMTP.js enables email functionality even without a network.
These are just a few examples of when sending mail directly from the client can be useful.
Common Questions
Here are answers to some frequently asked questions about using SMTP.js:
How does SMTP.js work without a server?
SMTP.js directly speaks the SMTP protocol to send mail. It is a client-side SMTP "server" connecting to real external servers. All the code is contained in the browser.
Is it secure to send email via client-side code?
SMTP.js is as secure as SMTP itself. All connections use TLS encryption, and credentials are not exposed client-side. The email contents and data stay local to the browser and JavaScript environment.
What is the advantage of a server-side solution?
It depends on the use case, but the advantages include no server dependencies, increased privacy, offline support, and reduced server load for things like contact forms.
What are the limitations?
Limitations include a lack of server-side templates, no central server log of sent mail, and reduced deliverability protections. Complex workflows involving mail merge and sending high volumes of email work better with a server.
How does email get delivered without a static IP address?
Services like Mailgun provide an SMTP API gateway with a consistent sending IP address and domain while masking the underlying client IPs. This helps improve deliverability.
Does SMTP.js work for sending bulk email?
SMTP.js can technically send bulk volumes, but server-side solutions are better suited for large mailing lists and newsletter campaigns. SMTP.js is better optimized for one-off transactional email.
Can SMTP.js connect to any SMTP service?
Yes, SMTP.js can connect to any standard SMTP provider or custom SMTP server with the proper credentials configured. Popular choices include Gmail, Mailgun, SparkPost, Amazon SES, or a self-hosted mail server.
Hopefully, this gives you a better understanding of how to use SMTP.js to send email directly from the browser! Let me know if you have any other questions.
If you find this article thrilling, discover extra thrilling posts like this on Learnhub Blog; we write a lot of tech-related topics from Cloud computing to Frontend Dev, Cybersecurity, AI, and Blockchain. Take a look at How to Build Offline Web Applications.
Top comments (24)
Exposing your SMTP username and password to front-end sounds like a terrible idea. For quick prototyping, maybe. But for production? Your credentials will be used to send spam in no time.
You can create the email form dynamically from a strongly encrypted js script.
That reduces dammatically the risk.
Please I know, nothing is it 100% secure, neither great firms.
True, Thanks
What is strongly encrypted js script? You mean minified?
No, truly obfuscated, look here : Obfuscator.
I am using smtp.js in production without any spams.
But it's still client side code. It still be in memory on user's device. It'll still be in javascript runtime.
Plus, you can easily reverse any obfuscation. Here is one for obfuscator.io:
obf-io.deobfuscate.io/
Yes, indeed...
But all is not lost :-)
Try this : DecryptMe
Hint : before IBM :-)
From PageCrypt
Everyone has their own poison, wouldn't you agree?
For the ones who are afraid to use it client side :
You can create the email form dynamically from a strongly encrypted js script.
That reduces dammatically the risk.
Thanks
Hy Scofield,
Thank you for this post.
I use smtp.js in my work, it's indeed a great library.
In order to prevent spamming, I create the contact form dynamically.
Cool!!
I have a few questions about this librery. I do not think anyone should use this in production. This is maybe a great way to teach your self about e-mail and Javascript.
Issues:
SPF will never be correct. E-mail's will never be delivered on scale. SPF (Sender Policy Framework) is designed to authenticate the sending IP address against the domain used in the email's "From" address. When you send email directly from the client's IP address, it is highly unlikely that this IP will be listed in the SPF record of the sending domain, resulting in SPF validation failure. This makes your emails more likely to be marked as spam or rejected altogether.
IP's get blacklisted and ISP do not clean them. ISPs typically don't proactively remove IPs from blacklists. Once an IP is blacklisted, it requires a manual delisting process, and there is no guarantee of success.
Username and password for an e-mail address in browser. Storing the username and password for an email address in the client-side JavaScript code exposes these credentials to anyone who can inspect the code. This is a major security risk that could lead to unauthorized access to the email account, allowing for a wide range of malicious activities including but not limited to sending spam or phishing emails, reading existing email, and potentially gaining access to other services tied to that email for password recovery.
While this library may have some useful educational purposes, it's important to be aware of the potential drawbacks you highlighted if considering production use cases. There are tradeoffs to evaluate with any email sending approach. Thanks for sharing your thoughtful analysis
I would never use this on the client in prod.
Sending emails isn't easy and neutral. You need to make sure that you're not getting marked as spam, that users are opening your emails, especially your transactional emails, eg password resets. You need to verify email addresses you're sending to, and ensure that you're not repeatedly sending to dead mail boxes.
If you don't do these things, you will get marked as a source of spam, and places like google will send your mails to the spam folder. I can't see how you would do any of this important stuff on the client in any way that wasn't serious.
This is all before you start worrying about SPF or a bunch of other things.
Please, don't use this in the client on prod. There are email sending businesses for a reason. Bootstrap without buying their services, send from your own servers if you're being super cheap, but after you've got a thousand users giving you money, buy a service. Its worth it. imo.
All of this is for educational base only. How you use it is left for each user to determine.
I think spam will be there even with paid service and more sophisticated platforms.
For anyone who know what they are doing they will be able to figure it all out.
Thanks and best regards.
It also needs proper rendering, which is known as full-featured representation of MVP The whole point of using MVP is to see how your product functions in an environment where people would be using it regularly. App Development Company In Kerala This goes on to help create the focus required for a sustainable business model or Process Driven Development (PDD).
I guess you are just trying to push the link, however, I have a better idea on creating simple to advance content that would rank and give visibility through Learnhub
Does this really keep user credential unexposed?
Plus, I cannot access to npm package and unpkg CDN.
Yes, the documentation says so.
According to smtpjs.com/, seems like you need encrypted 'secure token' instead of putting username and password to script visible to client as described in this post.
It was deprecated and going forward, tokens were introduced, I think SMTP does not have good documentation to transition users.
Cool! Great for quick prototyping! 🥳 Thank you! 🙏
If i put the password and username as environment variables, is that good enough?
how does that compares to obfusticating the javascript file?
Thanks