In this article, you'll learn three different ways to send Emails with Rust while discussing the pros & cons of each method.
Updated Jun 30, 2026
Email sending has become a common feature in modern applications since it is a fast, efficient, cost-effective communication method. As developers, we should have proper knowledge in implementing email-sending features in any language we work with to satisfy customer needs.
So, in this article, I will go over three ways to send emails using Rust to give you a better understanding.
Compared to other languages, email-sending options in Rust are limited. However, there are three main options for sending emails with Rust: SMTP, lettre and Amazon SES.
Let's go through the benefits and drawbacks followed by step-by-step tutorial for each option.
Simple Mail Transfer Protocol (SMTP) is a well-known protocol for sending emails across networks. When you send an email using an email service provider like Gmail, an outgoing SMTP server collects and connects it with the receiving server. SMTP defines the guidelines on how these two servers communicate and receive emails.
Sending emails with Rust and SMTP is pretty straightforward. First, you need to update the cargo.toml file with the dependencies. cargo.toml file is the manifest file used by the Rust package manager.
[dependencies]tokio = { version = "1", features = ["full"] }lettre = { version = "0.10.0-beta.2", default-features = false, features = ["smtp-transport", "tokio1-rustls-tls", "hostname", "r2d2", "builder"] }
Then, update your main.rs file with the below code to send emails.
use lettre::{transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message,Tokio1Executor,};#[tokio::main]// Creating basic data structure for the emailasync fn main() -> Result<(), Box<dyn std::error::Error>> {let smtp_credentials =Credentials::new("smtp_username".to_string(), "smtp_password".to_string());let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.email.com")?.credentials(smtp_credentials).build();let from = "Sender <sender@gmail.com>";let to = "receiver <receiver@gmail.com>";let subject = "Sending email with Rust";let body = "<h1>This is my first email</h1>".to_string();send_email_smtp(&mailer, from, to, subject, body).await}// Email sending functionasync fn send_email_smtp(mailer: &AsyncSmtpTransport<Tokio1Executor>,from: &str,to: &str,subject: &str,body: String,) -> Result<(), Box<dyn std::error::Error>> {let email = Message::builder().from(from.parse()?).to(to.parse()?).subject(subject).body(body.to_string())?;mailer.send(email).await?;Ok(())}
lettre is a mailer library that can be used to send emails with Rust. It was introduced in July 2022 and supports all the Rust versions after Rust 1.56.0. lettre has more than 975K downloads and healthy daily use.
As mentioned, using lettre is very simple. First, you have to update the cargo.toml file with lettre dependency.
[dependencies]lettre = "0.10"
Then, you can use the below code to send emails with your Rust application.
use lettre::transport::smtp::authentication::Credentials;use lettre::{Message, SmtpTransport, Transport};let email = Message::builder().from("Sender <sender@gmail.com>".parse().unwrap()).to("Receiver <receiver@gmail.com>".parse().unwrap()).subject("Sending email with Rust").body(String::from("This is my first email")).unwrap();let creds = Credentials::new("smtp_username".to_string(), "smtp_password".to_string());// Open a remote connection to gmaillet mailer = SmtpTransport::relay("smtp.gmail.com").unwrap().credentials(creds).build();// Send the emailmatch mailer.send(&email) {Ok(_) => println!("Email sent successfully!"),Err(e) => panic!("Could not send email: {:?}", e),}
Amazon Simple Email Service, or Amazon SES, is one of the most popular email services used in modern applications. Developers love to use it in their applications since it is highly scalable, flexible, and cost-effective. In addition, it ensures high security and eliminates most of the issues with traditional SMTP servers.
Having an AWS account is a mandatory requirement to use Amazon SES. If you don't have an AWS account, you can easily create a new account by following the steps in this guideline.
After creating an account, you can start implementing email service on your Rust application. First, you need to update the cargo.toml file with dependencies. Here, we are using rusoto_ses to create an SES client.
[dependencies]tokio = { version = "1", features = ["full"] }lettre = { version = "0.10.0-beta.2", default-features = false, features = ["builder"] }rusoto_core = { version = "0.46", default-features = false, features = ["rustls"] }rusoto_ses = { version = "0.46", default-features = false, features = ["rustls"] }base64 = "0.13"
Then, you can use the below code to send emails with your Rust application.
use lettre::Message;use rusoto_ses::{RawMessage, SendRawEmailRequest, Ses, SesClient};use std::env;#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> {let ses_client = SesClient::new(rusoto_core::Region::UsEast1);let from = "Sender <sender@gmail.com>";let to = "receiver <receiver@gmail.com>";let subject = "Sending email with Rust";let body = "<h1>This is my first email</h1>".to_string();send_email_ses(&ses_client, from, to, subject, body).await}async fn send_email_ses(ses_client: &SesClient,from: &str,to: &str,subject: &str,body: String,) -> Result<(), Box<dyn std::error::Error>> {let email = Message::builder().from(from.parse()?).to(to.parse()?).subject(subject).body(body.to_string())?;let raw_email = email.formatted();let ses_request = SendRawEmailRequest {raw_message: RawMessage {data: base64::encode(raw_email).into(),},..Default::default()};ses_client.send_raw_email(ses_request).await?;Ok(())}
This article discussed three methods we can use to implement email sending with Rust, alongside their pros and cons. I hope these suggestions will help you to implement the best email features for your Rust applications.
Keep exploring
One API, every channel
Courier gives you one API for email, SMS, push, and chat — with templates, routing, retries, and delivery logs built in.
Last updated Jun 30, 2026. Code samples are illustrative; provider APIs and pricing change over time — check each provider’s docs before relying on them.
© 2026 Courier. All rights reserved.