react-email icon indicating copy to clipboard operation
react-email copied to clipboard

Package `prettier` can't be external

Open coderrshyam opened this issue 6 months ago • 26 comments

Describe the Bug

Recently, I migrate to Biome from Prettier due to performance. After migration when i run my app using next dev I got error that Package prettier can't be external:

 ⚠ ./node_modules/.pnpm/@[email protected]_r_4cd7d00f12bf0fb695da21a0bfbc8367/node_modules/@react-email/render/dist/node
Package prettier can't be external
The request prettier/plugins/html matches serverExternalPackages (or the default list).
The request could not be resolved by Node.js from the project directory.
Packages that should be external need to be installed in the project directory, so they can be resolved from the output files.
Try to install it into the project directory by running npm install prettier from the project directory.

If user did not intrested in using prettier then why this type of warningis occured.

Which package is affected (leave empty if unsure)

react-email

Link to the code that reproduces this issue

https://github.com/resend/resend-nextjs-app-router-example

To Reproduce

  1. Configure Next.js app.
  2. Remove Prettier and integrate Biome.
  3. Do some basic setup for react-email
  4. Run the app, you see the issue.

Expected Behavior

There should be no error.

What's your node version? (if relevant)

22.18.0

coderrshyam avatar Aug 26 '25 14:08 coderrshyam

+1! Why is prettier in the normal dependencies? It's used for the templates?

lveillard avatar Aug 26 '25 17:08 lveillard

@lveillard it’s currently used in the pretty function, which formats emails in a way that feels familiar to users. However, this is expected to be replaced soon by the work @gabrielmfern is doing in this PR, which should allow us to remove the dependency altogether.

emiliosheinz avatar Aug 26 '25 19:08 emiliosheinz

Heads up, actually, we're most likely going to remove the pretty function and won't have #2361.

gabrielmfern avatar Aug 27 '25 12:08 gabrielmfern

Thank you for clarifying @gabrielmfern :)

emiliosheinz avatar Aug 27 '25 13:08 emiliosheinz

Hey @gabrielmfern any feedback regarding removing prettier from formatting.

coderrshyam avatar Sep 03 '25 12:09 coderrshyam

Hey @gabrielmfern and other maintainers. Could at least prettier be imported with await import() inside the function so users that don't actually format their final html have to bake prettier into the final production bundle of their app?

arthurfiorette avatar Sep 03 '25 23:09 arthurfiorette

@arthurfiorette we've started moving things to a pretty function that should do the trick for those cases, in the next major version we're going to drop the pretty option we had before.

gabrielmfern avatar Sep 04 '25 12:09 gabrielmfern

@gabrielmfern any idea on when it will be released? Would it be possible to do a first patch release with this dynamic import first if the rewrite is going to take too long?

arthurfiorette avatar Sep 04 '25 16:09 arthurfiorette

Was just about to write an issue about this, good that I searched first.

~~js-beautify is relatively small package.~~

Edit: you're prettifying html not js.

Handy command to probe the size of your installed packages:

du -sh node_modules/.pnpm/* | sort -h

hilja avatar Sep 19 '25 07:09 hilja

sadly i moved away from resend because of these annoying logs....

songkeys avatar Sep 19 '25 20:09 songkeys

sadly i moved away from resend because of these annoying logs....

@songkeys where you moved

coderrshyam avatar Sep 20 '25 10:09 coderrshyam

+1

johanazhu avatar Sep 24 '25 07:09 johanazhu

Just stumbled into this while upgrading. Currently handling it via a pinned version override in my package.json.

"//": "remove below once resolved: https://github.com/resend/react-email/issues/2426",
"pnpm": {
  "overrides": {
    "prettier": "3.6.0"
  }
}

Waiting on a new version where @react-email/render does not have prettier as a dep.

antonioGlavocevic avatar Oct 01 '25 07:10 antonioGlavocevic

I saw this is an open ticket for the Hacktoberfest. I wanted to clarify a few points.

  • Is this being worked on internally at the moment? I saw #2361 from earlier in this issues messages but it looks like work there has stopped.
  • Is the desired outcome a pretty function that could be user supplied or is this open to alternatives?
  • Is supplying a pretty function required, or can it pass back the string as is? I'm imagining for the @react-email/preview-serverthis could haveprettier` baked in as a dependency so there is at least some default there.

lukeshumard avatar Oct 01 '25 14:10 lukeshumard

@lukeshumard

Is this being worked on internally at the moment

No, that pull request was an exploration of how hard it would be to have an in-house formatter, and we're focusing on some other things right now.

Is the desired outcome a pretty function that could be user supplied or is this open to alternatives?

That's one idea to consider, what we have in mind, and haven't thought much about, is to not deal with prettying at all, and just leave it to users if they want to do it or not in their terms. So, in the future, users would just await render(...) and with then prettify the output if they want to.

Is supplying a pretty function required, or can it pass back the string as is? I'm imagining for the @react-email/preview-serverthis could haveprettier` baked in as a dependency so there is at least some default there.

I'm not absolutely sure I follow the question at the start

gabrielmfern avatar Oct 01 '25 16:10 gabrielmfern

I like the idea of not handling prettification within react-email and leaving that responsibility to users. It feels like a very niche feature, and removing it keeps the library lighter and easier to maintain since it reduces dependencies. We could even suggest some options in the documentation, so users don’t have to come up with solutions entirely on their own.

emiliosheinz avatar Oct 09 '25 15:10 emiliosheinz

sadly i moved away from resend because of these annoying logs....

You could just install prettier as a dependency pnpm i prettier or npm i prettier. The problem is that in the previous versions you'd need only resend, now you need resend, @react-email/render and prettier as dependencies

ebulku avatar Oct 11 '25 02:10 ebulku

sadly i moved away from resend because of these annoying logs....

You could just install prettier as a dependency pnpm i prettier or npm i prettier. The problem is that in the previous versions you'd need only resend, now you need resend, @react-email/render and prettier as dependencies

Installing Prettier as a regular dependency? No thanks, t's already a nightmare even with the -D flag šŸ˜…

lveillard avatar Oct 11 '25 17:10 lveillard

Frustrating. I wanted to start using react-email in a work project, but this is kind of a dealbreaker at the moment

johncmunson avatar Oct 14 '25 19:10 johncmunson

Frustrating. I wanted to start using react-email in a work project, but this is kind of a dealbreaker at the moment

You don't need this package :) I just started sending ascii art emails, they're great. Also writing simple html templates is not that hard, just don't use any fancy features. Resend as a service is great though.

hilja avatar Oct 14 '25 20:10 hilja

@gabrielmfern do you think we can move forward with deprecating both the pretty option (which is already) and the pretty function in order to later get rid of it completely? I can own it if that is the case.

emiliosheinz avatar Oct 15 '25 18:10 emiliosheinz

That's one idea to consider, what we have in mind, and haven't thought much about, is to not deal with prettying at all, and just leave it to users if they want to do it or not in their terms. So, in the future, users would just await render(...) and with then prettify the output if they want to.

I think this is certainly the best path forward.

As a sort-of middle ground, react-email could still have prettier declared as an optional peer dependency and then expose a pretty function that users can import and use if they really want to. But it would all be opt-in.

Or, like @gabrielmfern mentioned, it could just be entirely left to users to implement on their own, which I think would be perfectly fine.

johncmunson avatar Oct 20 '25 16:10 johncmunson

As most of us seem to be in favor of removing the pretty option and the pretty function to eliminate the prettier dependency, I’ve opened a PR to deprecate them: https://github.com/resend/react-email/pull/2581

Feel free to take a look and share your feedback.

One thing worth noting: the export command currently appears to redefine the pretty option, effectively ā€œun-deprecatingā€ it. I’m not entirely sure what the intention behind this is, but it’s likely something we’ll also want to deprecate since it seems to only be passed to the render function. See: https://github.com/resend/react-email/blob/canary/packages/react-email/src/commands/export.ts#L34. Maybe @gabrielmfern can help us clarify that?

emiliosheinz avatar Oct 20 '25 23:10 emiliosheinz

You don't need this package :) I just started sending ascii art emails, they're great.

It seems installing resend has @react-email/render as a peer dependency, which means this warning will be in your dev logs regardless if you use prettier or react-email.

Do I have this right then that the only choice is to either not use resend at all, or be forced to install prettier?

kdoran avatar Oct 22 '25 15:10 kdoran

@kdoran You don't need any deps to use Resend, I’ve found a simple fetch request to be sufficient for my needs:

const ResendSuccessSchema = z.object({ id: z.string().min(1) })

const email = {
  from: '[email protected]',
  html: '<html><body><p>Just a fetch :)</p></body></html>'
}

const response = await fetch('https://api.resend.com/emails', {
  method: 'POST',
  body: JSON.stringify(email),
  headers: {
    authorization: `Bearer ${process.env.RESEND_API_KEY}`,
    'Content-Type': 'application/json',
  },
})

const data = await response.json()
const parsedData = ResendSuccessSchema.safeParse(data)

If you want retries consider p-retry, or ky for other fancy things. Or if you need scheduling, QStash has a resend integration.

hilja avatar Oct 23 '25 13:10 hilja

I was encountering the same issue, and adding this to next.config.ts solved it: transpilePackages: ["prettier"]

MohamedArbani avatar Nov 24 '25 00:11 MohamedArbani

any update on this ?

xmlking avatar Jan 21 '26 20:01 xmlking

I gave up on using resend for this problem

EdamAme-x avatar Jan 23 '26 15:01 EdamAme-x

Next 16.1 with turbopack handles this. I no longer have warning.

mburumaxwell avatar Jan 24 '26 10:01 mburumaxwell

I dent want to add Prettier as runtime dependency. Switching to node mailer

xmlking avatar Jan 24 '26 16:01 xmlking