CosmoMail 2.0.4

dotnet add package CosmoMail --version 2.0.4
                    
NuGet\Install-Package CosmoMail -Version 2.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CosmoMail" Version="2.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CosmoMail" Version="2.0.4" />
                    
Directory.Packages.props
<PackageReference Include="CosmoMail" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CosmoMail --version 2.0.4
                    
#r "nuget: CosmoMail, 2.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CosmoMail@2.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CosmoMail&version=2.0.4
                    
Install as a Cake Addin
#tool nuget:?package=CosmoMail&version=2.0.4
                    
Install as a Cake Tool

CosmoMail

CosmoMail is a lightweight .NET 10 SMTP/IMAP stack built around direct socket transport, fluent message composition, MIME generation, inbox access, and Fluid-based templating.

It supports plain text and HTML bodies, attachments, inline images, STARTTLS, SMTP authentication including XOAUTH2, capability-aware SMTP sends (SIZE, PIPELINING, SMTPUTF8), reusable message/template objects for high-throughput send paths, lightweight IMAP inbox access including IDLE, mailbox/message management operations, and chunked/streaming MIME fetch support, decoded message-content fetches, and attachment extraction for downloads.

Features

  • Direct SMTP transport over sockets and System.IO.Pipelines
  • Fluent message builder for sender, recipients, headers, priority, text, and HTML
  • MIME generation for multipart/alternative, multipart/mixed, and multipart/related
  • Attachments and inline images with base64 encoding
  • STARTTLS and PLAIN / LOGIN / XOAUTH2 authentication helpers
  • Capability-aware SMTP send flow with SIZE, PIPELINING, and SMTPUTF8 support
  • Lightweight IMAP client for inbox login, mailbox selection, IDLE, mailbox list/create/delete/rename, message copy/move, partial/streaming raw message fetch, header listing, decoded message fetch, attachment extraction, read-state updates, and LOGIN / XOAUTH2 authentication
  • Fluid template support for reusable subject, text, and HTML rendering
  • UTF-8-safe header/body handling and structural response validation
  • Cached payload and envelope reuse for repeated sends of the same message

Usage

Simple Send

using CosmoMail;

var message = new SmtpMessage()
    .SetFrom("admin@company.com", "System Admin")
    .AddTo("vip@customer.com", "Important User")
    .AddCc("logs@company.com")
    .SetHighPriority()
    .SetSubject("Daily Analytics Snapshot")
    .SetBody("This is your raw system fallback output.")
    .SetHtmlBody("<h1>Daily Snapshot</h1><p>Welcome back!</p>");

await using var client = new CosmoMailClient("localhost", debug: true);

await client.ConnectAsync("mail.yourserver.com", 587);
await client.EhloAsync();
await client.StartTlsAsync("mail.yourserver.com");
await client.EhloAsync(); // Re-announce capabilities inside the TLS boundary
await client.AuthenticateAsync("LOGIN", "username", "secure_password");

await client.SendMessageAsync(message);
await client.QuitAsync();

Web UI

CosmoMailUI is the active browser UI for this repo. It is a Nuxt-based frontend backed by the CosmoMailUI .NET host and replaces the older Blazor management app.

For development, run the combined host from CosmoMailUI:

cd CosmoMailUI
dotnet run

For deployment or when you explicitly want the host and frontend managed separately, run them in separate terminals:

cd CosmoMailUI
dotnet run

cd CosmoMailUI/frontend
npm run dev

Default URLs:

http://localhost:3000/welcome
http://127.0.0.1:9183

Current UI capabilities include:

  • Login against saved mail server configurations
  • Register multiple SMTP/IMAP servers from the modal UI with create, edit, and delete flows, including SMTP/IMAP auth mode selection and saved OAuth access tokens
  • Gmail-style compose/reply modal with minimize, maximize, attachments, and rich-text editing
  • Inbox auto-refresh using IMAP IDLE-backed watch requests while the mailbox view is active
  • Mailbox selection plus create, rename, delete, copy, and move flows in the inbox UI
  • Automatic seen-state updates when opening a message
  • Gmail-style NEW badges for newly arrived unread messages
  • Inbox attachment download buttons for message attachments

Templates, Inline Images, and Attachments

using CosmoMail;

var template = new SmtpTemplate(
    subject: "Hello {{ Name }}! Your bill is ready.",
    html: @"
        <h1>Hey {{ Name }}!</h1>
        <p>Attached is your formal receipt generated at {{ Time }}.</p>
        <img src='cid:system-logo' alt='Company Logo' />"
);

var message = await template.RenderAsync(new { 
    Name = "John", 
    Time = DateTime.Now.ToString("F", System.Globalization.CultureInfo.InvariantCulture) 
});

message.SetFrom("billing@company.com", "Billing Dept")
       .AddTo("john.doe@company.com", "John Doe");

byte[] logoBytes = File.ReadAllBytes("logo.jpg");
message.WithInlineImage("system-logo", logoBytes, "image/jpeg");

byte[] pdfBytes = File.ReadAllBytes("receipt.pdf");
message.WithAttachment("receipt_2026.pdf", pdfBytes, "application/pdf");

// Transmit via `SendMessageAsync(message)`...

IMAP Inbox Access

using CosmoMail;

await using var imap = new CosmoImapClient("localhost", debug: false);

await imap.ConnectAsync("mail.yourserver.com", 143);
await imap.StartTlsAsync("mail.yourserver.com");
await imap.LoginAsync("username", "secure_password");

var mailbox = await imap.SelectMailboxAsync("INBOX");
var messages = await imap.ListMessageSummariesAsync(25);

foreach (var message in messages)
{
    Console.WriteLine($"{message.Date:u} {message.From} {message.Subject}");
}

await imap.LogoutAsync();

Testing & Confidence

CosmoMail.Tests uses mock TcpListener-based SMTP and IMAP servers to validate transport commands, EHLO capability parsing, SMTP extension handling, IMAP IDLE, mailbox operations, partial/streaming fetch behavior, UTF-8-safe payload generation, MIME structure, and failure paths.

The current suite contains 64 xUnit tests.

dotnet test

MailKit Parity

CosmoMail is not a full MailKit replacement. It targets a narrower subset of mail workflows with a smaller API surface and less protocol breadth.

Current practical parity looks like this:

Area CosmoMail MailKit
SMTP send flow Strong coverage for direct SMTP sends, multi-recipient envelopes, HTML/text bodies, attachments, inline images, custom headers, generated Message-ID, STARTTLS, SIZE, PIPELINING, SMTPUTF8, and LOGIN / PLAIN / XOAUTH2 auth Broader SMTP extension coverage, more auth mechanisms, more server interoperability work, richer diagnostics
IMAP inbox access Lightweight inbox operations: connect, TLS, LOGIN / XOAUTH2, SELECT, IDLE, mailbox list/create/delete/rename, message copy/move, partial/streaming raw fetch, list summaries, fetch decoded content, extract attachments, update seen state, and logout Full-featured IMAP client surface including richer search, folder operations, body-part access, message management, and protocol extensions
MIME/message model Focused send-side builder with practical delivery details covered for the UI scenarios, plus simplified decoded IMAP message content Much broader MIME model through MimeKit with richer parsing, traversal, and message manipulation
Operational maturity Good fit for the scenarios covered in this repository and the Nuxt management UI, especially compose/inbox workflows More complete general-purpose library for production mail interoperability across varied providers

Use CosmoMail when you want a small, direct .NET mail stack for the supported scenarios. Use MailKit when you need broad protocol coverage, richer MIME handling, or compatibility with a wider range of server capabilities.

Benchmarks

CosmoMail.Benchmarks contains three benchmark suites:

  • SMTP transport benchmarks that compare CosmoMailClient against MailKit using an in-process fake SMTP server
  • IMAP inbox benchmarks that compare CosmoImapClient against MailKit for lightweight inbox operations
  • template rendering benchmarks that measure SmtpTemplate render + MIME build cost directly
dotnet run -c Release --project CosmoMail.Benchmarks/CosmoMail.Benchmarks.csproj

For a fast in-process comparison without the full BenchmarkDotNet run:

dotnet run -c Release --project CosmoMail.Benchmarks/CosmoMail.Benchmarks.csproj -- --quick

The SMTP benchmark suite currently covers seven scenarios:

  • SimpleText: one plain-text message on a fresh connection
  • HeaderHeavy: reply-to, CC, BCC, priority, and custom headers
  • RichMime: HTML + text + inline image + attachments
  • AuthLogin: SMTP AUTH LOGIN on a plain connection
  • AuthPlain: SMTP AUTH PLAIN on a plain connection
  • StartTlsLogin: STARTTLS upgrade followed by AUTH LOGIN
  • Burst10: ten messages on one reused connection

Each SMTP scenario measures a full end-to-end send flow. Depending on the scenario, that includes:

  • ConnectAsync / ConnectAsync
  • EHLO
  • STARTTLS
  • AuthenticateAsync("LOGIN" | "PLAIN") / AuthenticateAsync
  • SendMessageAsync / SendAsync
  • QUIT / DisconnectAsync

Current stable SMTP BenchmarkDotNet results on this machine:

Scenario CosmoMail MailKit
SimpleText 263.9 us, 21.32 KB 285.0 us, 42.82 KB
HeaderHeavy 283.7 us, 24.33 KB 289.4 us, 45.09 KB
RichMime 449.3 us, 411.59 KB 846.1 us, 566.45 KB
AuthLogin 393.7 us, 24.23 KB 385.4 us, 51.98 KB
AuthPlain 313.4 us, 22.8 KB 323.9 us, 46.74 KB
StartTlsLogin 26.77 ms, 68.75 KB 28.10 ms, 110.55 KB
Burst10 1.350 ms, 72.67 KB 1.238 ms, 173.91 KB

The IMAP benchmark suite currently covers four scenarios:

  • ListSummaries: login, select mailbox, list recent message summaries, logout
  • FetchContent: login, select mailbox, fetch and decode one message body, logout
  • MarkAsRead: login, select mailbox, add \Seen, logout
  • InboxRoundTrip: list summaries, fetch one message body, then mark it read in one session

Current stable IMAP BenchmarkDotNet results on this machine:

Scenario CosmoMail MailKit
ListSummaries 307.5 us, 57.97 KB 459.1 us, 95.8 KB
FetchContent 263.0 us, 47.66 KB 554.0 us, 94.46 KB
MarkAsRead 241.5 us, 37.28 KB 447.4 us, 68.93 KB
InboxRoundTrip 386.8 us, 73.89 KB 586.2 us, 133.92 KB

Current template render + MIME build results:

Scenario CosmoMail
TemplateScenario0 1.892 us, 6.1 KB
TemplateScenario1 3.495 us, 9.21 KB

Latest generated reports:

  • BenchmarkDotNet.Artifacts/results/SmtpSendBenchmarks-report-github.md
  • BenchmarkDotNet.Artifacts/results/SmtpSendBenchmarks-report.csv
  • BenchmarkDotNet.Artifacts/results/SmtpSendBenchmarks-report.html
  • BenchmarkDotNet.Artifacts/results/ImapInboxBenchmarks-report-github.md
  • BenchmarkDotNet.Artifacts/results/ImapInboxBenchmarks-report.csv
  • BenchmarkDotNet.Artifacts/results/ImapInboxBenchmarks-report.html
  • BenchmarkDotNet.Artifacts/results/TemplateRenderBenchmarks-report-github.md
  • BenchmarkDotNet.Artifacts/results/TemplateRenderBenchmarks-report.csv
  • BenchmarkDotNet.Artifacts/results/TemplateRenderBenchmarks-report.html

Performance Notes

The current implementation includes a few transport and MIME-path optimizations that materially affect the benchmark results:

  • Cached UTF-8 wire payloads for repeated sends of the same SmtpMessage
  • Cached SMTP envelope commands (MAIL FROM and RCPT TO) for repeated sends
  • Direct PipeWriter command writes to avoid extra command-string encoding allocations
  • Simple-text fast path for non-multipart messages
  • Direct base64 appends into the final MIME builder instead of allocating intermediate base64 strings for each MIME part

These changes matter most for:

  • SimpleText, where transport overhead dominates
  • RichMime, where MIME serialization and allocation pressure dominate
  • Burst10, where reusing the same message across one SMTP session highlights payload and envelope caching
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.4 91 5/24/2026
2.0.3 91 5/24/2026
2.0.2 91 5/23/2026
2.0.1 93 5/23/2026
2.0.0 91 5/23/2026
1.1.7 159 4/25/2026
1.1.6 108 4/25/2026
1.1.5 130 4/23/2026
1.1.4 115 4/23/2026
1.1.3 115 4/23/2026
1.1.2 116 4/14/2026
1.1.1 100 4/14/2026
1.1.0 116 4/10/2026