Package `prettier` can't be external
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
- Configure
Next.jsapp. - Remove
Prettierand integrateBiome. - Do some basic setup for
react-email - Run the app, you see the issue.
Expected Behavior
There should be no error.
What's your node version? (if relevant)
22.18.0
+1! Why is prettier in the normal dependencies? It's used for the templates?
@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.
Heads up, actually, we're most likely going to remove the pretty function and won't have #2361.
Thank you for clarifying @gabrielmfern :)
Hey @gabrielmfern any feedback regarding removing prettier from formatting.
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 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 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?
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
sadly i moved away from resend because of these annoying logs....
sadly i moved away from resend because of these annoying logs....
@songkeys where you moved
+1
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.
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
prettyfunction that could be user supplied or is this open to alternatives? - Is supplying a
prettyfunction 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
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
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.
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
sadly i moved away from resend because of these annoying logs....
You could just install prettier as a dependency
pnpm i prettierornpm i prettier. The problem is that in the previous versions you'd need onlyresend, now you needresend,@react-email/renderandprettieras dependencies
Installing Prettier as a regular dependency? No thanks, t's already a nightmare even with the -D flag š
Frustrating. I wanted to start using react-email in a work project, but this is kind of a dealbreaker at the moment
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.
@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.
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.
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?
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 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.
I was encountering the same issue, and adding this to next.config.ts solved it:
transpilePackages: ["prettier"]
any update on this ?
I gave up on using resend for this problem
Next 16.1 with turbopack handles this. I no longer have warning.
I dent want to add Prettier as runtime dependency. Switching to node mailer