Skip to content
Development
Skill

/litestar-email

Auto-activate for litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, InMemoryBackend, SMTPConfig, ResendConfig, SendGridConfig, MailgunConfig, or SESConfig. Not for marketing APIs — use vendor SDKs.

From plugin
litestar
1431 skills1 agent1 hook
Install
$ npx -y skills add litestar-org/litestar-skills --skill litestar-email --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/litestar-email

Context preview

The summary Claude sees to decide when to auto-load this skill.

Auto-activate for litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, InMemoryBackend, SMTPConfig, ResendConfig, SendGridConfig, MailgunConfig, or SESConfig. Not for marketing APIs — use vendor SDKs.

SKILL.md

litestar-email.SKILL.md
name: litestar-email
description: "Auto-activate for litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, InMemoryBackend, SMTPConfig, ResendConfig, SendGridConfig, MailgunConfig, or SESConfig. Not for marketing APIs — use vendor SDKs."

litestar-email

`litestar-email` 0.4.0 provides one async sending interface for console, memory, SMTP, Resend, SendGrid, Mailgun, Amazon SES, and custom backends. Match the backend already selected by the project; keep message construction independent from the transport.

Code Style Rules

  • Use `NamedDependency[EmailService]` for handler injection. The plugin

registers a named Litestar dependency, not a global service singleton.

  • Pass recipient collections as `list[str]`. `to`, `cc`, `bcc`, and `reply_to`

are list fields.

  • Pass attachment content as `bytes`. Do file I/O before constructing the

message and keep that I/O async.

  • Await `send_message()` and `send_messages()`. Both return the count sent.
  • Keep API keys and SMTP credentials in the project's settings layer.

Quick Reference

Install

pip install "litestar-email>=0.4.0"
pip install "litestar-email[smtp]>=0.4.0"   # aiosmtplib
pip install "litestar-email[ses]>=0.4.0"    # botocore for SigV4
pip install "litestar-email[httpx]>=0.4.0"   # default HTTP transport
pip install "litestar-email[aiohttp]>=0.4.0" # alternative HTTP transport

The HTTP API backends select `httpx` by default, but the transport is optional in `litestar-email` itself. Install the `httpx` or `aiohttp` extra (unless the project already provides that dependency), and select `aiohttp` only when the project standardizes on it.

Configure the Plugin

from os import environ

from litestar import Litestar
from litestar_email import EmailConfig, EmailPlugin, SMTPConfig

email_config = EmailConfig(
    backend=SMTPConfig(
        host="smtp.example.com",
        port=587,
        username=environ["SMTP_USERNAME"],
        password=environ["SMTP_PASSWORD"],
        use_tls=True,
    ),
    from_email="noreply@example.com",
    from_name="Example App",
)

app = Litestar(plugins=[EmailPlugin(config=email_config)])

`EmailConfig` fields:

| Field | Default | Contract | | --- | --- | --- | | `backend` | `"console"` | Registered name, import path, or built-in backend config object | | `from_email` | `"noreply@localhost"` | Default sender address | | `from_name` | `""` | Default display name | | `fail_silently` | `False` | Backend-specific best-effort delivery behavior | | `email_service_dependency_key` | `"mailer"` | Litestar DI key | | `email_service_state_key` | `"mailer"` | Key holding the config in app state |

The dependency and state keys occupy separate namespaces. Change them independently when the application already uses either key:

email_config = EmailConfig(
    backend="memory",
    email_service_dependency_key="email_service",
    email_service_state_key="email_config",
)

Inject `EmailService`

The handler parameter name must match `email_service_dependency_key`:

from litestar import post
from litestar.di import NamedDependency
from litestar_email import EmailMessage, EmailService


@post("/notifications")
async def send_notification(
    mailer: NamedDependency[EmailService],
) -> dict[str, int]:
    sent = await mailer.send_message(
        EmailMessage(
            subject="Notification",
            body="You have a new notification.",
            to=["recipient@example.com"],
        ),
    )
    return {"sent": sent}

`EmailPlugin.on_app_init()` registers:

  • `config.provide_service` under `email_service_dependency_key`;
  • the public email types in Litestar's signature namespace;
  • the `EmailConfig` instance under `email_service_state_key` in app state.

App state does not contain a permanently open `EmailService`. Use `plugin.get_service(app.state)` or `config.get_service(app.state)` when code outside handler DI needs a service derived from app state.

Construct Messages

`subject` and `body` are required constructor arguments. Recipient lists have empty-list defaults, so provide at least one delivery recipient before sending.

from litestar_email import EmailMessage

message = EmailMessage(
    subject="Monthly report",
    body="The report is attached.",
    from_email="Reports <reports@example.com>",
    to=["owner@example.com"],
    cc=["audit@example.com"],
    bcc=["archive@example.com"],
    reply_to=["support@example.com"],
    headers={"X-Campaign-ID": "monthly-report"},
)
message.attach(
    filename="report.pdf",
    content=b"report content",
    mimetype="application/pdf",
)
message.attach_alternative(
    content="<p>The report is attached.</p>",
    mimetype="text/html",
)

`EmailMessage` does not accept `html_body` or `from_name`. Put a per-message display name in `from_email`, as shown above. Use `EmailMultiAlternatives.html_body` for the HTML convenience constructor:

from litestar_email import EmailMultiAlternatives

message = EmailMultiAlternatives(
    subject="Welcome",
    body="Welcome to Example App.",
    to=["user@example.com"],
    html_body="<p>Welcome to <strong>Example App</strong>.</p>",
)

The message collections have these exact shapes:

| Field | Type | | --- | --- | | `to`, `cc`, `bcc`, `reply_to` | `list[str]` | | `headers` | `dict[str, str]` | | `attachments` | `list[tuple[str, bytes, str]]` | | `alternatives` | `list[tuple[str, str]]` |

`recipients()` returns `to + cc + bcc`; it does not include `reply_to`.

Pick a Backend

| Existing project constraint | Configuration | Extra | | --- | --- | --- | | Local output only | `backend="console"` | None | | Unit or integration tests | `backend="memory"` | None | | SMTP server or Mailpit | `backend=SMTPConfig(...)` | `smtp` | | Existing Resend account | `backend=ResendConfig(...)` | `httpx` or `aiohttp` | | Existing SendGrid account | `backend=SendGridConfig(...)` | `httpx` or `aiohttp` | | Exi

Read more
Ships withlitestar

Opinionated, first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework and its ecosystem — publishable to every major AI agent and IDE from a single repo.

Get the whole plugin

Other skills on litestar.