This FRD ships @dmwd-io/email as an optional package that re-exports resend as the platform standard for transactional email. The value is standards and drift prevention, not a custom abstraction — consuming apps get a canonical import path and documented env var conventions rather than each wiring up the SDK independently.
Introduction
Overview
Per ADR-014 (Open Source First), we designate resend as the community library for transactional email and re-export it through @dmwd-io/email. This gives the platform a single canonical import path, documents RESEND_API_KEY as the standard env var, and prevents drift across services. No custom EmailProvider interface or adapter layer is built — the resend library’s own API is the interface.
Goals
Designate resend as the platform standard for transactional email.
Re-export resend via @dmwd-io/email so consuming apps use a single import path.
Document RESEND_API_KEY as the platform env var convention.
Add only platform conventions (PII sanitization guidance, default from-address) on top of the library’s own API.
Non-Goals
Marketing email or bulk-send capabilities.
Email template authoring or storage (templates are owned by consuming applications).
Building a custom provider interface or adapter layer — the library’s own API is the interface (per ADR-014).
Scope
In Scope
Item
Description
packages/@dmwd-io/email/
New package directory.
packages/@dmwd-io/email/package.json
Package manifest with resend as a peer dependency.
packages/@dmwd-io/email/src/index.ts
Re-exports all named exports from resend.
Env var documentation
RESEND_API_KEY documented in .env.example and the package README.
Unit tests
Verify the re-export surface matches the upstream package.
Out of Scope
Item
Reason
Email template design
Application concern, not provider concern.
Bounce/complaint webhooks
Phase 2 work; this FRD covers send-only.
Rate limiting
Handled by the provider’s built-in rate limiting.
Users and Pain Points
User
Pain Point
Application developer
No platform-standard import path for email; each service picks its own integration pattern.
Platform maintainer
Drift across services makes it impossible to enforce PII log hygiene or update the SDK in one place.
Operations
No standardized email sending means no unified logging or monitoring for email delivery.
Definitions
Term
Definition
resend
The community library designated as the platform standard for transactional email.
@dmwd-io/email
The thin re-export package that makes resend the canonical import for platform services.
Transient error
A temporary failure (HTTP 429 or 5xx) that may succeed on retry.
The EmailProvider interface with send() and sendBatch() methods.
An in-memory mock implementation (createInMemoryEmailProvider) that records sent messages for test assertions.
A TODO at line 102: // TODO: Replace with real provider (e.g. Resend, SendGrid).
No production adapter exists. Applications that need email either call Resend directly (without going through the provider abstraction) or skip email in development.
Proposed Solution
@dmwd-io/email is a thin re-export package. It adds no custom interface or adapter layer.
await resend.emails.send({ from, to, subject, html });
No custom interface is built — the library’s API is the interface.
Platform conventions
RESEND_API_KEY is the standard env var name across all platform services.
Logs must not include the API key or recipient email addresses (PII sanitization is the responsibility of the calling code).
defaultFrom for each service is documented in that service’s own configuration, not in this package.
Requirements
ID
Priority
Requirement
EMAIL-01
P0
@dmwd-io/email re-exports all named exports from resend.
EMAIL-02
P0
resend is listed as a peer dependency, not a bundled dependency.
EMAIL-03
P0
RESEND_API_KEY is documented in .env.example and the package README.
EMAIL-04
P1
TSDoc on the index.ts re-export module explains the platform convention.
Functional Requirements
import { Resend } from '@dmwd-io/email' resolves correctly in consuming packages.
The package does not add runtime overhead beyond a re-export.
The package README documents the standard env var name and a minimal usage example.
Non-Functional Requirements
Category
Requirement
Dependency size
Package adds no runtime code beyond a re-export shim.
Secrets
API keys are passed via RESEND_API_KEY env var, never hardcoded.
Observability
Calling code must not log the API key or recipient addresses (PII).
Testability
Consumers use resend’s own test utilities or mock the module at the import boundary.
API/Interface Requirements
The resend library’s own API is the interface. No custom wrapper types are defined in this package. See the resend Node.js SDK docs for the full API surface.
Accessibility Requirements
Not applicable. This is a headless library with no UI surface.
Content and Documentation Requirements
Package README with a minimal usage example and RESEND_API_KEY setup instructions.
Add RESEND_API_KEY to the project’s .env.example.
Dependencies
Dependency
Type
Notes
resend
Peer (npm)
Official Resend Node SDK. Listed as peerDependency so consuming apps control the version.
ADR-014
Governance
Open Source First principle — designate community library, thin re-export only.
ADR-051
Governance
Provider pattern architecture.
Risks and Tradeoffs
Risk
Likelihood
Impact
Mitigation
Resend SDK has breaking changes.
Low
Medium
Pin to a specific major version range in the peerDependency.
Re-export pattern offers no enforcement of PII hygiene.
Medium
Medium
Document in README; enforce via lint rule or code-review checklist.
API key leaked in error logs.
Low
High
Calling code is responsible; README documents this explicitly.
Open Questions
Should the package expose a pre-configured factory (e.g. createResendClient()) that reads RESEND_API_KEY automatically, or leave instantiation fully to the caller?
Should we add a rate-limiter wrapper in the package, or rely on the provider’s built-in rate limiting?
Acceptance Criteria
import { Resend } from '@dmwd-io/email' resolves and types correctly.
resend is a peerDependency in package.json, not a direct dependency.
RESEND_API_KEY is present in .env.example with a comment.
Package README includes a minimal usage example.
pnpm typecheck passes.
pnpm vitest run --project unit passes.
LLM Handoff Instructions
When implementing this FRD:
Create packages/@dmwd-io/email/ if the packages directory does not already exist.
Create packages/@dmwd-io/email/package.json with resend listed under peerDependencies (not dependencies). Set main, module, and types fields appropriately.
Create packages/@dmwd-io/email/src/index.ts containing export * from 'resend';.
Add RESEND_API_KEY= to the project’s .env.example with a brief comment.
Create a minimal README.md in the package directory documenting the env var and a usage example.
Run pnpm typecheck and pnpm vitest run --project unit.
Decision Log
Date
Decision
Rationale
2026-05-26
Resend as primary, SendGrid as fallback.
Resend has a simpler API and better developer experience. SendGrid provides a widely-adopted fallback for enterprise environments.
2026-05-26
Separate entry points per adapter.
Avoids bundling unused SDKs. Each app imports only the adapter it configures.
2026-05-26
Defer attachments to follow-up.
Current use cases (password reset, verification, notifications) are text/HTML only.
2026-06-02
Reframed per ADR-014 (Open Source First): adopt resend as thin re-export rather than building a custom provider interface. Library API is the interface.
ADR-014 establishes that we designate community libraries as standards and avoid building custom abstractions on top of them.
Document History
Version
Date
Author
Changes
0.1
2026-05-26
David Holmes
Initial draft.
0.2
2026-06-02
David Holmes
Reframed per ADR-014: ship as thin re-export of resend, drop custom interface.