Email And Notifications
Use @bnomei/emdash-mika/email for built-in email rendering helpers.
Mika ships default rows and renderers for magic links and order confirmations. Other notification kinds are hook-only until default renderers are intentionally added.
Trusted backends can pass a notification hook to createMikaBackendApi(). Returning { handled: true } suppresses Mika’s default email for the intent when one exists.
Notification flow:
| Stage | Owner |
|---|---|
Operation emits MikaNotificationIntent |
Mika backend |
| Optional host hook handles or declines the intent | Host app |
| Built-in renderer creates default email when one exists | Mika |
| Outbox runner leases and sends queued rows | Mika runner plus host sender |
| Transport, sender identity, retries outside the outbox, and deliverability | Host app |
Package Roles
Section titled “Package Roles”| File or subpath | Role |
|---|---|
@bnomei/emdash-mika/email |
Pure rendering helpers for built-in transactional templates. |
@bnomei/emdash-mika/server |
Exports notification hook types, email outbox runner helpers, and the backend API constructor. |
src/api/notifications.ts |
Defines notification intent kinds and emitMikaNotification(). |
src/api/email-outbox.ts |
Leases queued email documents, renders built-in templates, calls the host sender, and records retry state. |
src/api/maintenance.ts |
Runs the optional email outbox task when an emailOutboxRunner is configured. |
Mika does not include an SMTP, SES, Postmark, Resend, or EmDash account configuration. The host owns the actual transport and sender identity.
Renderers
Section titled “Renderers”Built-in renderer exports:
mikaEmailTemplates;renderMikaMagicLinkEmail();renderMikaOrderConfirmationEmail();renderMikaEmail(template, input);MikaEmailBrand;MikaRenderedEmail;MikaMagicLinkEmailInput;MikaOrderConfirmationEmailInput.
renderMikaEmail() dispatches by template key. Built-in template keys are
magic_link and order_confirmation.
Notification Hook
Section titled “Notification Hook”Pass a hook to createMikaBackendApi({ notifications: { handle } }). The hook receives an intent and returns { handled: true } to suppress Mika’s default email for that kind:
import { renderMikaMagicLinkEmail } from "@bnomei/emdash-mika/email";
const notifications = { handle: async (intent) => { if (intent.kind === "magic_link.requested") { const email = renderMikaMagicLinkEmail({ toEmail: intent.context.toEmail, url: intent.context.link, purpose: intent.context.purpose, expiresAt: intent.context.expiresAt, }); await deliver(email); // host-owned transport return { handled: true }; } return { handled: false }; },};Notification kinds include magic_link.requested, order.confirmed, checkout.payment_failed, download.ready, license.issued, subscription.started / updated / renewal_failed, account.export_ready, account.delete_requested, and ops.webhook_failed. Default renderers ship only for magic_link.requested and order.confirmed (renderMikaMagicLinkEmail, renderMikaOrderConfirmationEmail, or the generic renderMikaEmail); the rest are hook-only until you render and deliver them.
emitMikaNotification() first calls the host hook. If the hook is missing or
does not return { handled: true }, the backend runs the default handler for
that intent when one exists. The default handlers enqueue outbox records for
magic links and order confirmations.
Outbox Runner
Section titled “Outbox Runner”Use createMikaEmailOutboxRunner() from @bnomei/emdash-mika/server when the
host wants Mika to drain queued email documents:
import { createEmDashMikaEmailSender, createMikaEmailOutboxRunner,} from "@bnomei/emdash-mika/server";
const emailOutboxRunner = createMikaEmailOutboxRunner({ repositories, sender: createEmDashMikaEmailSender(locals.emdash.email), brand: { siteName: "Acme Shop", supportEmail: "support@example.com" },});The runner:
- reads due emails from the ops repository;
- leases each email before delivery;
- renders
magic_linkororder_confirmation; - calls the host
MikaEmailSender; - marks emails sent, failed, skipped,
lease_missed, orlease_lost; - computes retry timing with
retryDelayMsor default retry behavior.
createEmDashMikaEmailSender() adapts locals.emdash.email into a Mika sender.
It expects the EmDash sender to accept a source argument unless
allowPluginScopedSender is set.
Maintenance runs the outbox only if the plugin/native entrypoint passes an
emailOutboxRunner. Otherwise the email outbox maintenance task is skipped.
Next: Backend And Provider shows the hook in context. Maintenance lists the scheduled outbox task result.
Source Anchors
Section titled “Source Anchors”- ⓟ
../emdash-mika/src/email.ts - ⓟ
../emdash-mika/src/server.ts - ⓟ
../emdash-mika/src/api/notifications.ts - ⓟ
../emdash-mika/src/api/email-outbox.ts - ⓟ
../emdash-mika/src/api/backend.ts - ⓟ
../emdash-mika/src/api/maintenance.ts