Description
When using resend with React email templates on Cloudflare Workers via OpenNext, sending emails fails at runtime with:
Failed to render React component. Make sure to install `@react-email/render` or `@react-email/components`.
@react-email/render is installed. This worked on Next.js 15 (webpack) and broke on Next.js 16 (Turbopack).
Root Cause
@react-email/render provides conditional exports in its package.json:
workerd → dist/edge/index.mjs (uses WritableStream — works on Workers)
node → dist/node/index.mjs (uses node:stream — fails on Workers)
Turbopack always picks the node entry. The resulting chunk is named node_modules_@react-email_render_dist_node_index_mjs_*.js and contains require("node:stream").
OpenNext's esbuild runs after Turbopack with conditions: ["workerd"], but Turbopack has already resolved the wrong entry. The workerd condition never gets a chance.
Webpack (Next.js 15) correctly resolved to the edge-compatible build with WritableStream and zero node:stream references.
Reproduction
https://github.com/zammitjohn/resend-cloudflare-repro
git clone https://github.com/zammitjohn/resend-cloudflare-repro.git
cd resend-cloudflare-repro
npm install
npm run preview
# Click "Send Test Email" → fails
Verify the wrong resolution
npx opennextjs-cloudflare build
# Turbopack chose the node entry:
ls .open-next/server-functions/default/.next/server/chunks/ssr/ | grep react-email
# → node_modules_@react-email_render_dist_node_index_mjs_*.js
# The chunk requires node:stream:
grep 'require("node:stream")' .open-next/server-functions/default/.next/server/chunks/ssr/\[root-of-the-server\]__*.js
Versions
| Package |
Broken (Turbopack) |
Working (webpack) |
next |
16.1.5 |
15.5.9 |
@opennextjs/cloudflare |
^1.17.1 |
^1.14.4 |
resend |
^6.10.0 |
^6.6.0 |
@react-email/render |
^2.0.6 |
^2.0.0 |
Description
When using
resendwith React email templates on Cloudflare Workers via OpenNext, sending emails fails at runtime with:@react-email/renderis installed. This worked on Next.js 15 (webpack) and broke on Next.js 16 (Turbopack).Root Cause
@react-email/renderprovides conditional exports in itspackage.json:workerd→dist/edge/index.mjs(usesWritableStream— works on Workers)node→dist/node/index.mjs(usesnode:stream— fails on Workers)Turbopack always picks the
nodeentry. The resulting chunk is namednode_modules_@react-email_render_dist_node_index_mjs_*.jsand containsrequire("node:stream").OpenNext's esbuild runs after Turbopack with
conditions: ["workerd"], but Turbopack has already resolved the wrong entry. The workerd condition never gets a chance.Webpack (Next.js 15) correctly resolved to the edge-compatible build with
WritableStreamand zeronode:streamreferences.Reproduction
https://github.com/zammitjohn/resend-cloudflare-repro
Verify the wrong resolution
Versions
next@opennextjs/cloudflareresend@react-email/render