Sending Email in Rust: lettre and async-smtp Libraries for Mailings

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Sending Email in Rust: lettre and async-smtp Libraries

Sending emails is a basic function of any educational or commercial website. In the Rust ecosystem, there are several mature solutions for this task. In this article, we will cover the two most popular libraries: lettre (synchronous sending) and async-smtp (asynchronous sending). You will learn how to configure an SMTP client, send a simple email, add attachments, and handle errors.



1. The lettre Library — Synchronous Sending

lettre is a modular library for working with email protocols (SMTP, SMTPS, STARTTLS). It supports:

  • Sending via an external SMTP server (Gmail, Yandex, Mail.ru, custom).
  • Support for MIME formats (text, HTML, attachments).
  • TLS/SSL encryption.
  • Working with encodings (Base64, quoted-printable).


1.1. Installing lettre

Add to Cargo.toml:

[dependencies]lettre = "0.11"lettre_email = "0.11"  # deprecated, but still used# For the async version — lettre with feature "tokio1" or "async-std1"


1.2. Example: Sending a Simple Email via SMTP

use lettre::transport::smtp::authentication::Credentials;use lettre::transport::smtp::SmtpTransport;use lettre::message::Message;use lettre::MessageBuilder;

fn main() { // Create the email let email = Message::builder() .from("sender@example.com".parse().unwrap()) .to("recipient@example.com".parse().unwrap()) .subject("Hello from Rust!") .body("This is a test email sent using the lettre library.".to_string()) .unwrap();

// SMTP server settings (example for Gmail) let creds = Credentials::new("your_email@gmail.com".to_string(), "your_password".to_string());

// Open a secure connection let mailer = SmtpTransport::starttls_relay("smtp.gmail.com") .unwrap() .credentials(creds) .build();

// Send match mailer.send(&email) { Ok(_) => println!("Email sent successfully!"), Err(e) => eprintln!("Sending error: {}", e), }}


1.3. Example: Email with HTML Content and Attachment

use lettre::message::{MultiPart, SinglePart};use lettre::Message;

fn build_html_email() -> Message { // HTML part let html_part = SinglePart::builder() .header(lettre::message::header::ContentType::TEXT_HTML) .body(String::from("<h1>Hello!</h1><p>This is an HTML email.</p>"));

// Attachment (e.g., a PDF file) let attachment = SinglePart::builder() .header(lettre::message::header::ContentType::parse("application/pdf").unwrap()) .body(vec![0x25, 0x50, 0x44, 0x46]); // placeholder for PDF

// Build the multipart email Message::builder() .from("from@example.com".parse().unwrap()) .to("to@example.com".parse().unwrap()) .subject("Email with HTML and attachment") .multipart( MultiPart::mixed() .multipart(MultiPart::alternative().singlepart(html_part)) .singlepart(attachment), ) .unwrap()}


2. Asynchronous Sending: async-smtp

The async-smtp library is designed for non-blocking email sending in asynchronous applications (e.g., in conjunction with tokio or async-std). It uses the same API as lettre, but with async/await.



2.1. Installing async-smtp

[dependencies]async-smtp = "0.6"tokio = { version = "1", features = ["full"] }


2.2. Example: Asynchronous Sending

use async_smtp::{SmtpClient, SmtpTransport};use async_smtp::authentication::Credentials;use lettre::message::Mess                    

Recommendations