Skip to content

Conversation

gabrielmfern
Copy link
Member

@gabrielmfern gabrielmfern commented Aug 25, 2025

This pull request makes use of the new tailwindcss@4 API, and a new CSS parser called css-tree. It makes the code much simpler (since Tailwind now exposes a function to generate styles), much smaller (since we only need to bundle css-tree for a distribution issue csstree/csstree#352) and it gets slightly faster than the previous version.

The pull request also introduces a few changes to the changes we made for email compatibility to work well with the new CSS features used in tailwindcss@4.

Currently available on npm through @react-email/[email protected]

Compatibility

tailwindcss@4 introduces the use of some new CSS features in certain ways that email clients don't support, here's a list of them and the respective way of how we change the genreate CSS to have better email client support.

  • Uses oklch as the default color function, which is almost not supported at all: we convert it, and most other colors to rgb(red,green,blue,alpha) syntax
  • Uses calc expressions extensively (e.g. m-* utiltiies): we evaluate simple calc expressions which should be enough for the vast majority of the utilites that have
  • Uses border-radius:calc(Infinity*1px) instead of 9999px for rounded-full: Convert to using 9999px instead directly

There might still be some other compatibility issues that we can't see, and some ones that I suspect might not be supported so we still need to test it on Litmus before releasing a stable version.

Performance

After the initial changes to actually get tests working, I noticed performance issues, where just email rendering would get into a few a seconds for not such a complicated email template. One of the reasons was code introduced in this pull request to deal with compatibility issues, but it was mainly because of repeated parse calls to css-tree. I knew this was the case after profiling with Node.js's profiling and the flamegraphs in https://discoveryjs.github.io/cpupro.

Before tailwindcss@4, we were using using postcss which was the same CSS parser that was used for tailwindcss@3 so it made integration much simpler. Now, with tailwindcss@4 they're using their own seemingly proprietary minimal CSS parser that is not exposed, meaning we need to pick one ourselves. With that new parser, we end up also repeatedly parsing the CSS coming from tailwind instead of reusing what already has parsed under the hood.

To actually get reasonable performance running with tailwindcss@v4, by avoiding repeatedly parsing the CSS returned from the build function coming from tailwindcss, this pull request also introduces a new way of inlining styles for components.

Before this pull request, we would always inline styles for components and elements alike. But, for components, we did not strip away the original classes that were associated with the inlined styles. Now, we only inline styles for elements, and not for any component, unless the component has under a specific list of our components that need the styles (e.g., Button).

This is actually a much more intuitive user experience than what we had before since it brings it closer to what users would already be used to when using tailwindcss.

@gabrielmfern gabrielmfern self-assigned this Aug 25, 2025
@changeset-bot
Copy link

changeset-bot bot commented Aug 25, 2025

⚠️ No Changeset found

Latest commit: fa41ec7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Aug 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
react-email Ready Ready Preview Comment Oct 17, 2025 8:07pm
react-email-demo Ready Ready Preview Comment Oct 17, 2025 8:07pm

💡 Enable Vercel Agent with $100 free credit for automated AI reviews

@pkg-pr-new
Copy link

pkg-pr-new bot commented Aug 25, 2025

Open in StackBlitz

npm i https://pkg.pr.new/resend/react-email/@react-email/components@2425
npm i https://pkg.pr.new/resend/react-email/@react-email/preview-server@2425
npm i https://pkg.pr.new/resend/react-email@2425
npm i https://pkg.pr.new/resend/react-email/@react-email/tailwind@2425

commit: fa41ec7

…pec.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@CHC383
Copy link
Contributor

CHC383 commented Oct 16, 2025

tailwindcss@4 uses lightningcss to transform the css file, not sure if you have compared it with css-tree, and if its APIs are sufficient for the task.

@gabrielmfern
Copy link
Member Author

@CHC383 ideally we'd use the same as them, but they don't actually use it on the tailwindcss package (which is what we're depending on here).

They instead use a minimal in-house version of a postcss-like parser that they don't export https://github.com/tailwindlabs/tailwindcss/blob/de6b54c30743528d4baeaa81b46c090c9f160b53/packages/tailwindcss/src/css-parser.ts#L39-L39

@gabrielmfern
Copy link
Member Author

@SocketSecurity ignore npm/@swc/[email protected]

@gabrielmfern gabrielmfern merged commit 97ae4e3 into canary Oct 17, 2025
15 checks passed
@gabrielmfern gabrielmfern deleted the chore/try-using-tailwind-v4-at-runtime branch October 17, 2025 20:08
gabrielmfern added a commit that referenced this pull request Oct 17, 2025
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Bu Kinoshita <[email protected]>
gabrielmfern added a commit that referenced this pull request Oct 17, 2025
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Bu Kinoshita <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants