Version, currently main branch1 version
- main branchlatestJan 24, 2026
github.com/jgaskins/mail
Send email over SMTP with Crystal
Installation
# Add this to your shard.yml
dependencies:
mail:
github: jgaskins/mail
branch: mainmain is a branch, not a release, so this tracks it rather than pinning a version.
Then run:
shards installshard.yml
- Crystal
>= 1.16.3- License
- MIT
- Author
- Jamie Gaskins
Dependencies
Runtime Dependencies
- db*github: crystal-lang/crystal-db
- mime-extensions*github: jgaskins/mime-extensions
Development Dependencies
- dotenv*github: gdotdesign/cr-dotenvdev
README
Crystal shard that sends email over SMTP.
Installation
-
Add the dependency to your
shard.yml:dependencies: mail: github: jgaskins/mail -
Run
shards install
Usage
require "mail"
Instantiate the mail client. This can be a constant or in your application's config:
# src/config/mail.cr
# Using a constant
MAIL = Mail::Client.new ENV["SMTP_SERVER"], 587,
domain: ENV["SMTP_DOMAIN"],
auth: Mail::Auth::Login.new(ENV["SMTP_LOGIN"], ENV["SMTP_PASSWORD"])
# Using some kind of application-level configuration
Config.define mail : Mail::Client = Mail::Client.new ENV["SMTP_SERVER"], 587,
domain: ENV["SMTP_DOMAIN"],
auth: Mail::Auth::Login.new(ENV["SMTP_LOGIN"], ENV["SMTP_PASSWORD"])
Then you can send messages:
MAIL.send Mail::Message.new(
from: "me@example.com",
to: ["you@example.com"],
subject: "Howdy",
parts: [
Mail::Message::Part.text("Hey there!"),
],
)
Note that to, cc, and bcc are arrays, even when there is a single recipient. You do not have to specify cc or bcc if there aren't any.
Personalizing sender and recipients
The sending party and all receiving parties (to, cc, and bcc) can either be Strings or Mail::Party instances. The purpose of a Mail::Party is to provide both a human-readable name for the mail client to display as well as an email address.
MAIL.send Mail::Message.new(
from: Mail::Party.new(name: "Admin", address: "admin@example.com"),
to: [
Mail::Party.new(name: "Example User", address: "user@example.com"),
],
# ...
)
On mail clients, this will display the sender as Admin and the recipient as Example User.
Sending HTML with Text fallback
Some email clients don't support HTML emails, so you can provide both HTML and text versions of the email:
MAIL.send Mail::Message.new(
# ...
parts: [
Mail::Message::Part.html(html_content),
Mail::Message::Part.text(text_content),
],
)
Attachments
You can also attach files to messages:
File.open(filename) do |file|
MAIL.send Mail::Message.new(
# ...
parts: [
Mail::Message::Part.html("Please see the attached file"),
Mail::Message::Part.attachment(
filename: File.basename(filename),
content_type: "image/jpg",
body: file,
),
],
)
end
The file will be streamed to the SMTP server and will not be loaded all into memory at once.
Contributing
- Fork it (https://github.com/jgaskins/mail/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Jamie Gaskins - creator and maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This branch
- Branch
main- Seen
- Jan 24, 2026
- Crystal
>= 1.16.3- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/jgaskins/mail
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 14, 2026
- Synced
- Aug 14, 2026
- Versions
- 1