Swoosh for Elixir email composition, delivery, and testing
Compose, deliver and test your emails easily in Elixir
At a glance
- What is it?
- Swoosh gives Elixir applications a common interface for composing email and sending it through providers, SMTP, local delivery, or tests. Its main value is the adapter boundary, although provider-specific capabilities still depend on the selected adapter.
- Who is it for?
- Elixir teams that want one email interface across development, testing, SMTP, and hosted providers should adopt Swoosh. Projects centered on provider-specific bulk campaign features should first verify adapter support.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Elixir, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Swoosh's Elixir email boundary
Swoosh addresses a specific Elixir application problem: application code should not need to construct provider payloads or implement a separate delivery path for every email service. It provides functions for composing an email, a mailer module connected to an adapter, and adapters for services including SendGrid, Mandrill, Mailgun, Postmark, Amazon SES, and standard SMTP. It also lists Local and Test adapters, which place development delivery and test handling behind the same general interface.
The intended audience is Elixir developers who send transactional messages from an OTP application, including Phoenix applications. The README's controller example places `Mailer.deliver(email)` after user creation, showing that Swoosh is designed to fit into application workflows rather than operate as a separate mail server. Its Phoenix example does not make Phoenix a dependency or part of Swoosh's core architecture. Phoenix is one supported calling context.
This is an Elixir library, not an email delivery service. It does not provide an inbox, a hosted sending account, or a provider account on the application's behalf. An operator still needs credentials and an appropriate delivery destination. The library handles the application-side composition and adapter boundary, while the configured provider, SMTP server, Sendmail installation, or local mechanism performs the actual handoff.
Email data flow through Swoosh.Mailer
The visible data flow begins with `import Swoosh.Email`. A module calls `new()` and pipes that email through functions such as `to`, `from`, `subject`, `html_body`, and `text_body`. The result is an email value assembled by application code. In the README example, `Sample.UserEmail.welcome/1` accepts a user map containing a name and email address, then places those values into the recipient and body fields.
Delivery moves through a separate module created with `use Swoosh.Mailer, otp_app: :sample`. The `otp_app` connects mailer configuration to the application's environment. The configuration selects `Swoosh.Adapters.Sendgrid` and supplies an `api_key`, after which the application passes the composed email to `Sample.Mailer.deliver(email)`. This division keeps message construction separate from delivery configuration.
For non-SMTP adapters, Swoosh generally uses `Swoosh.ApiClient`. The README states that `Swoosh.ApiClient.Hackney` is configured by default and that applications using it must include `hackney`. It also supports `Swoosh.ApiClient.Finch` and `Swoosh.ApiClient.Req`. Local, Test, and SMTP-based adapters do not require this API client, so applications using those paths can set the configuration to `false`. Another client can be integrated through the `Swoosh.ApiClient` behaviour.
Installing Swoosh and sending the first welcome email
Swoosh requires Elixir 1.16 or later and Erlang OTP 26 or later. Add the library to the dependencies in `mix.exs`. The README uses the `~> 1.29` requirement for its main installation example.
def deps do
[{:swoosh, "~> 1.29"}]
endFor a hosted API adapter such as SendGrid, configure the mailer in `config/config.exs`. The `api_key` below is the README's placeholder, not a usable credential.
config :sample, Sample.Mailer,
adapter: Swoosh.Adapters.Sendgrid,
api_key: "SG.x.x"
endDefine the mailer and an email-building module. The `from`, recipient, subject, and body values can then be changed to match the application.
defmodule Sample.Mailer do
use Swoosh.Mailer, otp_app: :sample
end
defmodule Sample.UserEmail do
import Swoosh.Email
def welcome(user) do
new()
|> to({user.name, user.email})
|> from({"Dr B Banner", "[email protected]"})
|> subject("Hello, Avengers!")
end
endFor the first real use, build the email in an IEx session and pass it to the configured mailer. The README presents `deliver/1` as the operation that initiates delivery through the selected adapter.
email = Sample.UserEmail.welcome(%{name: "Tony Stark", email: "[email protected]"})
Sample.Mailer.deliver(email)The README does not document the return shape or show the provider response for this call. That omission matters during setup: successful construction of the email does not document what a caller should expect from `deliver/1`. The README identifies HexDocs as the place for additional `Swoosh.Mailer` configuration options.
Choosing the correct Swoosh adapter dependency
Adapter choice determines which extra dependencies are needed. Non-SMTP adapters generally communicate through `Swoosh.ApiClient`. The default is `Swoosh.ApiClient.Hackney`, so selecting that path requires adding `hackney`. Swoosh also accepts Finch and Req without requiring application code to define a custom client.
If the application does not use `Swoosh.ApiClient` at all, it can disable that subsystem. This applies to Local, Test, and adapters based on SMTP.
config :swoosh, :api_client, falseSMTP, Sendmail, and Amazon SES have a separate dependency requirement. Their installation example adds `gen_smtp`.
def deps do
[
{:swoosh, "~> 1.6"},
{:gen_smtp, "~> 1.0"}
]
endThat example retains the older `~> 1.6` Swoosh constraint even though the main installation section recommends `~> 1.29`. Readers should not treat the two snippets as one new application configuration without resolving the version choice deliberately. The documented adapter table shows both `Swoosh.Adapters.AmazonSES` and `Swoosh.Adapters.ExAwsAmazonSES`, so an Amazon SES integration also requires a choice between the adapter implementations.
A custom HTTP client is possible without replacing Swoosh. Define a module that follows the `Swoosh.ApiClient` behaviour and select it with the `api_client` configuration. The README does not document retry, timeout, or observability behavior for custom clients, so those properties cannot be inferred from the behaviour alone.
Swoosh's limitations and provider boundary
The common interface does not make every provider feature interchangeable. Swoosh's adapters normalize email composition and delivery paths, but the repository information does not claim that templates, campaigns, scheduling, suppression lists, analytics, or provider-specific API options have identical support across providers. Applications that depend on a distinctive provider operation must check that adapter's HexDocs page.
The adapter list exposes implementation choices that are not interchangeable. SMTP, Sendmail, Amazon SES, hosted provider APIs, Local delivery, and Test handling have different operational requirements. The application must have an API client for most non-SMTP adapters, while SMTP, Sendmail, and Amazon SES require `gen_smtp`. A developer switching from an API adapter to SMTP is therefore changing more than a provider name.
The README does not document rollback, delivery queues, background jobs, idempotency, automatic retries, failure callbacks, or message scheduling. Their absence from the README is not proof that no such facility exists elsewhere in Swoosh, but it means these behaviors cannot be credited from the available repository description. HexDocs remains the documented place for adapter options and mailer behavior.
Swoosh is also the wrong abstraction when provider-specific API operations dominate the application. Calling a provider directly gives that integration access to the complete request model without Swoosh's adapter abstraction. The trade-off is that each provider then needs its own client, payload, credentials, error handling, and test arrangement.
Swoosh releases, upgrades, and the MIT license
The repository is not archived, and its last push was on 2026-10-14. Recent releases include v1.29.0 on 2026-10-08, v1.28.1 on 2026-09-16, and v1.28.0 on 2026-08-23. Those facts indicate recent repository and release activity, but they do not establish compatibility with every application, provider account, or future API change.
The dependency constraint is one part of upgrade planning. The README's main installation example uses `{:swoosh, "~> 1.29"}`, while its SMTP dependency example uses `{:swoosh, "~> 1.6"}`. An upgrade should also account for `hackney`, `finch`, `req`, or `gen_smtp`, depending on the selected adapter. The README does not provide upgrade procedures or migration notes, so `CHANGELOG.md` and the relevant versioned HexDocs are the concrete files and references to inspect when moving between versions.
Swoosh is distributed under the MIT license. That permits use, modification, distribution, and sublicensing subject to the license conditions, including preservation of its copyright and permission notice. This is a license summary rather than legal advice. Provider services, DNS configuration, account restrictions, and external software retain their own terms, which the Swoosh license does not replace.
Editorial conclusion
Elixir teams that want one email interface across development, testing, SMTP, and hosted providers should adopt Swoosh. Projects centered on provider-specific bulk campaign features should first verify adapter support. Before adoption, check the documented configuration for the exact adapter, confirm the Elixir 1.16 and Erlang OTP 26 requirements, and decide which HTTP or SMTP dependencies the selected delivery path requires.
Frequently asked questions
What are Swoosh's minimum Elixir and Erlang requirements?
The README requires Elixir 1.16 or later and Erlang OTP 26 or later.
Which HTTP clients can Swoosh use for provider adapters?
Swoosh accepts Hackney, Finch, and Req. Its default API client is `Swoosh.ApiClient.Hackney`, while Local, Test, and SMTP-based adapters can run with `Swoosh.ApiClient` disabled.
When should an Elixir project add gen_smtp for Swoosh?
The README says to add `gen_smtp` when using `Swoosh.Adapters.SMTP`, `Swoosh.Adapters.Sendmail`, or `Swoosh.Adapters.AmazonSES`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/swoosh-swoosh)Was this useful?