Skip to content

email · side by side

Postmark vs Resend for a Next.js app

Both fill the email slot, so a generated repo carries one or the other, never both. Every line below is read out of the two manifests.

Short answer

Pick Postmark if

Products where the transactional mail has to arrive now: sign-in links, password resets, receipts. Also teams that send some marketing and want it kept on separate infrastructure from the mail that must not fail.

Pick Resend if

Product teams sending transactional mail: magic links, receipts, notifications. Templates are React components, reviewed in a pull request, not pasted into a vendor's WYSIWYG editor.

Side by side

Price, obligations, and the surface each one adds. No row is written by hand. This is manifest.yaml, rendered.

Postmark compared with Resend on pricing, fit, trade-offs, required companions, environment variables, dependencies, MCP servers and repo footprint.
From the manifestOption APostmarkOption BResend
In one linePostmark

Transactional email with separate broadcast streams and 45 days of history.

Resend

Transactional email with React Email templates you review in a pull request.

PricingPostmark

Free developer plan: 100 emails a month, no expiry. Paid plans start at $15/month for 10,000 emails. Every plan keeps 45 days of message history by default. Dedicated IPs (from $50/month) and longer retention are add-ons.

Resend

Free: 3,000 emails a month (100 a day) on up to 3 domains. Pro is $20/month for 50,000 emails and 10 domains. Every self-serve plan keeps 30 days of data. Dedicated IPs are a $30/month add-on on Scale.

Best forPostmark

Products where the transactional mail has to arrive now: sign-in links, password resets, receipts. Also teams that send some marketing and want it kept on separate infrastructure from the mail that must not fail.

Resend

Product teams sending transactional mail: magic links, receipts, notifications. Templates are React components, reviewed in a pull request, not pasted into a vendor's WYSIWYG editor.

Trade-offsVerbatim from the manifestPostmark
  • Transactional first. Broadcast streams exist and handle unsubscribes, but there is no segmentation, no drip builder and no marketing CRM.
  • Postmark does not sign webhooks. The endpoint is protected by basic auth over HTTPS, which works but puts the credential in the webhook config.
  • No React rendering on Postmark's side. Templates are rendered to HTML and text in the app before sending, so the preview is exactly what ships.
  • No idempotency key on the API. This battery sets a deterministic Message-ID and stores the key as metadata instead.
  • New accounts go through a short approval before they can mail outside their own domain. Plan a day for it before launch.
Resend
  • Transactional first. There is a broadcast product, but if you need segmentation, drip campaigns and a marketing CRM, this is not that tool.
  • Shared IPs by default. Dedicated IPs are a paid add-on on the Scale plan, so on the shared pool your own sending hygiene matters more.
  • Data is kept 30 days. If you need to prove what you sent someone six months ago, log the message id at send time. The repo does.
  • React Email is the headline feature and a real one: templates are components, previewable locally, diffable in review. It also means your email templates are part of your build.
  • Fewer knobs than a full ESP: no server-side template variables, no A/B testing, limited routing rules. For transactional mail that is a simpler model, not a gap.
Required companionsAdded for you, with a reasonPostmark

Nothing. It stands on its own.

Resend

Nothing. It stands on its own.

Recommended alongsideSuggested, never added for youPostmark
  • An ORM battery
Resend
  • An ORM battery
Env vars you will manageEvery one documented in docs/onboard.mdPostmark

8 variables · 2 required

  • EMAIL_FROM
  • POSTMARK_SERVER_TOKEN
  • EMAIL_OUTBOX_DIR
  • POSTMARK_BROADCAST_STREAM
  • POSTMARK_MESSAGE_STREAM
  • POSTMARK_WEBHOOK_PASSWORD
  • POSTMARK_WEBHOOK_USERNAME
  • REPLY_TO
Resend

5 variables · 2 required

  • EMAIL_FROM
  • RESEND_API_KEY
  • EMAIL_OUTBOX_DIR
  • REPLY_TO
  • RESEND_WEBHOOK_SECRET
Dependencies addedPostmark
  • @react-email/render ^2.1.0
  • postmark ^5.1.0
  • react-email ^6.11.0
  • server-only ^0.0.1
Resend
  • @react-email/render ^2.1.0
  • react-email ^6.11.0
  • resend ^6.30.0
  • server-only ^0.0.1
  • svix ^2.5.0
MCP serversWritten into .mcp.jsonPostmark
  • postmark: npx -y @activecampaign/postmark-mcp@2.1.1
Resend

None. No extra agent tools from this one.

Footprint in your repoPostmark

29 files, plus 3 injections into shared stack files

Resend

26 files, plus 3 injections into shared stack files

What changes in your repo

The paths each battery contributes, diffed. A path in the third list is written by both, so swapping rewrites that file rather than adding one.

Only with Postmark (5)

  • scripts/1 file
    • email/1 file
      • suppressions.ts
  • src/4 files
    • app/1 file
      • api/1 file
        • webhooks/1 file
          • postmark/1 file
            • route.ts
    • lib/3 files
      • email/3 files
        • templates/1 file
          • layout.tsx
        • postmark.ts
        • webhook-auth.ts

Only with Resend (2)

  • src/2 files
    • app/1 file
      • api/1 file
        • webhooks/1 file
          • resend/1 file
            • route.ts
    • lib/1 file
      • email/1 file
        • resend.ts

Same path, different implementation (24)

  • scripts/2 files
    • email/2 files
      • render-samples.ts
      • send-test.ts
  • src/12 files
    • lib/12 files
      • email/12 files
        • templates/6 files
          • magic-link.tsx
          • receipt.tsx
          • reset-password.tsx
          • theme.ts
          • verify-email.tsx
          • welcome.tsx
        • address.ts
        • index.ts
        • outbox.ts
        • retry.ts
        • suppression.ts
        • tags.ts
  • tests/2 files
    • unit/2 files
      • email-outbox.test.ts
      • email.test.ts
  • variants/8 files
    • errors-none/1 file
      • src/1 file
        • lib/1 file
          • email/1 file
            • observability.ts
    • errors-sentry/1 file
      • src/1 file
        • lib/1 file
          • email/1 file
            • observability.ts
    • orm-drizzle/3 files
      • slots/1 file
        • db-schema.ts
      • src/2 files
        • db/1 file
          • email-schema.ts
        • lib/1 file
          • email/1 file
            • store.ts
    • orm-none/1 file
      • src/1 file
        • lib/1 file
          • email/1 file
            • store.ts
    • orm-prisma/2 files
      • slots/1 file
        • prisma-models.prisma
      • src/1 file
        • lib/1 file
          • email/1 file
            • store.ts

Shared stack files Postmark injects into

  • env-required
  • legal-processors
  • verify-checks

Shared stack files Resend injects into

  • env-required
  • legal-processors
  • verify-checks

Postmark in your .env.local

.env.localbash11 lines
# required
EMAIL_FROM=my-app <hello@mail.example.com>
POSTMARK_SERVER_TOKEN=POSTMARK_API_TEST

# optional
EMAIL_OUTBOX_DIR=
POSTMARK_BROADCAST_STREAM=broadcast
POSTMARK_MESSAGE_STREAM=outbound
POSTMARK_WEBHOOK_PASSWORD=replace_with_a_long_random_string
POSTMARK_WEBHOOK_USERNAME=postmark
REPLY_TO=support@example.com

Resend in your .env.local

.env.localbash8 lines
# required
EMAIL_FROM=my-app <hello@mail.example.com>
RESEND_API_KEY=re_replace_me

# optional
EMAIL_OUTBOX_DIR=
REPLY_TO=support@example.com
RESEND_WEBHOOK_SECRET=whsec_replace_me

What changes for your agents

Each battery ships rules, skills, subagents and hooks that an agent loads before it touches the code that battery owns. Picking one is also picking how your agents behave in src/lib/email/**.

Postmark

  • 2

    Skills

  • 1

    Rules

  • 6

    Solution docs

  • 1

    MCP servers

Rules (1)

One send path, the right message stream, and respect for inactive recipients

src/lib/email/** · src/app/api/webhooks/postmark/** · src/db/email-schema.ts · scripts/email/** · src/lib/auth/** · src/lib/billing/**

Skills (2)

/add-email-template

Add a React Email template on the shared layout, pick its message stream, wire it into a sendEmail call, and prove it lands in a real inbox.

/test-email

Prove Postmark sending works. Check the token and stream, send one of each template, read the activity feed, check suppressions, and test the basic-auth webhook with a fake bounce.

Subagents and hooks

None of its own. The foundation agents and guard hooks still ship.

Resend

  • 2

    Skills

  • 1

    Rules

  • 5

    Solution docs

Rules (1)

Every email goes through sendEmail, from a verified domain, with a reply-to

src/lib/email/** · src/app/api/webhooks/resend/** · src/lib/auth/** · src/lib/billing/**

Skills (2)

/add-email-template

Add a React Email template, preview it, wire it into a send, and check it renders and lands in a real inbox.

/preview-and-test-email

Diagnose an email problem (not sending, landing in spam, rendering wrong) in the order that finds the cause fastest.

Subagents and hooks

None of its own. The foundation agents and guard hooks still ship.

What each one already knows

Solution docs land in docs/solutions/ in your repo and are published here, so you can read the failure modes before you commit.

Postmark (6)

Resend (5)

Which one to pick

From meta.bestFor and meta.tradeoffs. If a claim is not in the manifest, it is not on this page.

Pick Postmark when

Products where the transactional mail has to arrive now: sign-in links, password resets, receipts. Also teams that send some marketing and want it kept on separate infrastructure from the mail that must not fail.

And accept that(5)
  • Transactional first. Broadcast streams exist and handle unsubscribes, but there is no segmentation, no drip builder and no marketing CRM.
  • Postmark does not sign webhooks. The endpoint is protected by basic auth over HTTPS, which works but puts the credential in the webhook config.
  • No React rendering on Postmark's side. Templates are rendered to HTML and text in the app before sending, so the preview is exactly what ships.
  • No idempotency key on the API. This battery sets a deterministic Message-ID and stores the key as metadata instead.
  • New accounts go through a short approval before they can mail outside their own domain. Plan a day for it before launch.

Pick Resend when

Product teams sending transactional mail: magic links, receipts, notifications. Templates are React components, reviewed in a pull request, not pasted into a vendor's WYSIWYG editor.

And accept that(5)
  • Transactional first. There is a broadcast product, but if you need segmentation, drip campaigns and a marketing CRM, this is not that tool.
  • Shared IPs by default. Dedicated IPs are a paid add-on on the Scale plan, so on the shared pool your own sending hygiene matters more.
  • Data is kept 30 days. If you need to prove what you sent someone six months ago, log the message id at send time. The repo does.
  • React Email is the headline feature and a real one: templates are components, previewable locally, diffable in review. It also means your email templates are part of your build.
  • Fewer knobs than a full ESP: no server-side template variables, no A/B testing, limited routing rules. For transactional mail that is a simpler model, not a gap.

Questions people actually ask

Should I choose Postmark or Resend?
Postmark is best for products where the transactional mail has to arrive now: sign-in links, password resets, receipts. Also teams that send some marketing and want it kept on separate infrastructure from the mail that must not fail. Resend is best for product teams sending transactional mail: magic links, receipts, notifications. Templates are React components, reviewed in a pull request, not pasted into a vendor's WYSIWYG editor. Both fill the email slot, so a generated repo carries one or the other, never both.
How much do Postmark and Resend cost?
Postmark: Free developer plan: 100 emails a month, no expiry. Paid plans start at $15/month for 10,000 emails. Every plan keeps 45 days of message history by default. Dedicated IPs (from $50/month) and longer retention are add-ons. Resend: Free: 3,000 emails a month (100 a day) on up to 3 domains. Pro is $20/month for 50,000 emails and 10 domains. Every self-serve plan keeps 30 days of data. Dedicated IPs are a $30/month add-on on Scale.
What changes in my repo if I switch from Postmark to Resend?
Postmark writes 29 files, 8 environment variables and 4 dependencies, and installs 1 path-scoped rule, 2 skills and 6 solution docs. Resend writes 26 files, 5 environment variables and 5 dependencies, and installs 1 path-scoped rule, 2 skills and 5 solution docs.

Decide once, then build the repo that already knows the decision.

Either way you get that choice’s rules, skills and solution docs installed, plus the guard hooks, an onboarding doc for exactly these env vars, and the Compound Engineering loop. Free and MIT.