Files
2026-08-07 17:57:12 -03:00

149 lines
7.6 KiB
Plaintext

---
title: 'Codebase overview'
sidebarTitle: 'Codebase overview'
'og:image': 'https://react.email/static/covers/react-email.png'
description: 'An overview of the React Email codebase'
icon: 'folder-tree'
---
We've created this guide to help new contributors understand and navigate the React Email codebase.
## Top-level directories
After cloning the [React Email repository](https://github.com/resend/react-email) you will see a few root-level directories. Here's a brief overview of each:
<table>
<thead>
<tr>
<th>Directory</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
[apps](https://github.com/resend/react-email/tree/canary/apps)
</td>
<td>
Here you can find all of the apps related to our online presence, like:
- this documentation (under [apps/docs](https://github.com/resend/react-email/tree/canary/apps/docs)),
- the demo emails we have on [demo.react.email](https://demo.react.email/preview/Community/notifications/vercel-invite-user)
(under [apps/demo](https://github.com/resend/react-email/tree/canary/apps/demo))
- the Next app we have for our landing page on [react.email](https://react.email) (under [apps/web](https://github.com/resend/react-email/tree/canary/apps/web))
</td>
</tr>
<tr>
<td>
[benchmarks](https://github.com/resend/react-email/tree/canary/benchmarks)
</td>
<td>
We make benchmarks from version-to-version to demonstrate data-observable performance gains with metrics like *p99 and p75*.
For example, see the [Improved Performance for Tailwind Emails](https://resend.com/blog/improved-performance-for-tailwind-emails) benchmark.
</td>
</tr>
<tr>
<td>
[packages](https://github.com/resend/react-email/tree/canary/packages)
</td>
<td>
Most contributions will be made to the packages in this directory.
This directory contains all our published [NPM](https://www.npmjs.com/) packages.
Many subdirectories are individual components published as their own packages, alongside packages for the CLI, editor, rendering utilities, and shared configuration.
</td>
</tr>
</tbody>
</table>
<Note>
Feel free to [open a discussion](https://github.com/resend/react-email/discussions/new?category=ideas) if you have suggestions on how to better structure these packages to make them more manageable and approachable.
</Note>
## Multiple packages
The react-email repository is a [pnpm monorepo](https://pnpm.io/next/workspaces), which means it contains
multiple packages.
Because we use pnpm, you will need to use [pnpm](https://pnpm.io/) to install and run each package. If you do not have pnpm installed, follow the [pnpm installation guide](https://pnpm.io/installation):
```bash
npm install -g pnpm
```
Currently, we have the following packages:
- [react-email](https://github.com/resend/react-email/tree/canary/packages/react-email)
- <span className="text-xs">The package for our [email CLI](/cli), and for all of our components</span>
- [@react-email/editor](https://github.com/resend/react-email/tree/canary/packages/editor)
- <span className="text-xs">The embeddable visual editor for composing React Email templates</span>
- [@react-email/render](https://github.com/resend/react-email/tree/canary/packages/render)
- <span className="text-xs">The [render](/utilities/render) utility. Can also be imported from `react-email`.</span>
- [@react-email/ui](https://github.com/resend/react-email/tree/canary/packages/ui)
- [create-email](https://github.com/resend/react-email/tree/canary/packages/create-email)
- <span className="text-xs">Used for our [automatic setup](/getting-started/automatic-setup)</span>
### Turborepo
We encourage using [turborepo](https://turbo.build/repo) to manage the packages.
It's often helpful to [install Turborepo globally](https://turbo.build/repo/docs/installing) to make it easier to run commands in any of the repositories. With a global installation, running `turbo build` in any of the packages will build both the package
you are on as well as the dependent packages. The global installation handles [version mismatching as well](https://turbo.build/repo/docs/installing#install-per-repository).
### The React Email CLI
The CLI is built using [commander](https://www.npmjs.com/package/commander), a CLI builder for node. It handles
parsing of command line arguments and ensuring that the syntax for the command is as expected.
The `build`, `dev`, and `start` commands all depend on the user first installing `@react-email/ui`.
Locally installing the preview server also includes all the required dependencies so you can run the necessary commands.
[nypm](https://www.npmjs.com/package/nypm) and [jiti](https://www.npmjs.com/package/jiti) work together to first ensure `@react-email/ui` is installed and then to import it into the CLI.
The Preview Server and the CLI work together. The CLI detects changes to files
in the user's dependency graph with [chokidar](https://www.npmjs.com/package/chokidar) and then sends
the updated files to the Preview Server using [socket.io](https://socket.io/). Other details, like the path to the user's emails directory, are handled through environment variables.
### The Preview Server
The Preview Server is a Next.js app that uses `esbuild` at runtime to bundle the
user's email templates and then renders them using the [render](/utilities/render) utility.
As changes from the CLI are passed through [socket.io](https://socket.io/) to the Preview Server, the preview updates automatically.
## Testing
For testing, we use [vitest](https://vitest.dev/). We prefer to define globals and run tests under the `happy-dom` environment.
We do not strictly enforce testing coverage, but encourage it.
For help testing, see our [Development workflow guide](/contributing/development-workflow/2-running-tests).
<Note>
The `@react-email/render` package's `renderAsync` does a fair bit of magic to simulate `edge` and other environments that are not supported by `happy-dom`. For this use case, we override the [environment on a per-file basis](https://vitest.dev/guide/environment#environments-for-specific-files) for its tests
</Note>
## Linting
We use [biomejs](https://biomejs.dev/) for linting and formatting. Both the linting and formatting are ensured by our GitHub CI so make sure you lint and format your code (`pnpm lint:fix`) before opening a PR or asking for a review on it.
For help linting and formatting, see our [Development workflow guide on linting](/contributing/development-workflow/3-linting).
## Building
We use [tsup](https://github.com/egoist/tsup) to build most packages. (The only exception for this is the `@react-email/tailwind` package which currently uses `vite` due to a few issues with `tsup` and `tailwindcss`'s bundling.) For help building packages, see our [Development workflow guide](/contributing/development-workflow/4-building).
<Note>
Building in each package will run `tsup` with a few settings, typically `src/index.ts --format esm,cjs --dts --external react`.
Tsup handles building both ESM and CJS versions along with the type definitions exported from the entry point, `src/index.ts`, without bundling `react`, which can cause issues.
</Note>
### Why build before publishing?
We build most of the packages before publishing for a few reasons:
1. All the exported types can be imported from the same place the JavaScript is imported
2. We have proper [CommonJS](https://nodejs.org/docs/latest/api/modules.html#modules-commonjs-modules)
and [ES Modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules) support
3. Code that isn't exported is not published or downloaded