npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@buchida/render

v0.3.0

Published

Server-side render React email components to HTML and plain text

Downloads

461

Readme

@buchida/render

Render React email components to email-safe HTML and plain text.

Built by buchida — Email API for Asia & Beyond.

Install

npm install @buchida/render

Peer dependencies: react, react-dom

Quick Start

import { render } from "@buchida/render";
import WelcomeEmail from "./emails/welcome";

// Render to HTML
const html = render(<WelcomeEmail name="김민준" locale="ko" />);

// Send with buchida
import Buchida from "buchida";
const client = new Buchida(process.env.BUCHIDA_API_KEY);
await client.emails.send({
  from: "[email protected]",
  to: "[email protected]",
  subject: "환영합니다",
  html,
});

API

render(element, options?)

Renders a React element to a complete HTML email string.

import { render, type RenderOptions } from "@buchida/render";

const html = render(<WelcomeEmail />, {
  pretty: false,  // default: false
  minify: false,  // default: false
});

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | element | ReactElement | The React component tree to render | | options | RenderOptions | Optional render configuration |

RenderOptions:

| Option | Type | Default | Description | |--------|------|---------|-------------| | pretty | boolean | false | Indent the HTML output for readability | | minify | boolean | false | Collapse whitespace and strip comments |

Returns: string — Complete HTML string starting with <!DOCTYPE html ...>

renderToText(element)

Renders a React element to plain text by stripping HTML tags.

import { renderToText } from "@buchida/render";

const text = renderToText(<WelcomeEmail />);
// Plain text version without any HTML tags

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | element | ReactElement | The React component tree to render |

Returns: string — Plain text string with normalized whitespace

Options

pretty: true — Readable HTML

const html = render(<WelcomeEmail />, { pretty: true });

Indents the HTML output for debugging. Do not use in production — adds whitespace that can affect email client rendering.

minify: true — Compact HTML

const html = render(<WelcomeEmail />, { minify: true });

Strips unnecessary whitespace and collapses newlines. Recommended for production sends where email size matters (Gmail clips emails at 102KB).

MSO Conditional Processing

The render() function automatically converts MsoConditional and MsoHide components from @buchida/email into proper Outlook conditional comments.

import { MsoConditional, MsoHide } from "@buchida/email";

// In your template:
<MsoConditional>
  <table width="600"><tr><td>
</MsoConditional>
  <div style={{ maxWidth: "600px" }}>Content</div>
<MsoConditional>
  </td></tr></table>
</MsoConditional>

After render(), the output becomes:

<!--[if mso]>
<table width="600"><tr><td>
<![endif]-->
<div style="max-width:600px">Content</div>
<!--[if mso]>
</td></tr></table>
<![endif]-->

This solves the fundamental limitation of React's inability to render HTML comments, giving you full Outlook ghost-table support.

Plain Text

Use renderToText to generate the plain text alternative for multi-part emails:

import { render, renderToText } from "@buchida/render";

const html = render(<WelcomeEmail />);
const text = renderToText(<WelcomeEmail />);

await client.emails.send({
  from: "[email protected]",
  to: "[email protected]",
  subject: "Welcome",
  html,
  text, // fallback for email clients that don't support HTML
});

The plain text render:

  • Strips all HTML tags
  • Converts <br> and block elements to newlines
  • Converts <hr> to ---
  • Decodes HTML entities (&amp;&, &lt;<, etc.)
  • Normalizes whitespace

Server-Side Usage

@buchida/render works in any Node.js environment (≥18):

// Express route
app.get("/preview/:templateId", async (req, res) => {
  const { templateId } = req.params;
  const { locale = "en" } = req.query;

  const Template = await import(`./emails/${templateId}`);
  const html = render(<Template.default locale={locale} />);

  res.setHeader("Content-Type", "text/html");
  res.send(html);
});

// Next.js server action
"use server";
import { render } from "@buchida/render";

export async function sendWelcomeEmail(userId: string) {
  const user = await db.users.findById(userId);
  const html = render(<WelcomeEmail name={user.name} locale={user.locale} />);
  await emailClient.send({ to: user.email, html });
}

DOCTYPE

The rendered HTML includes a proper XHTML transitional DOCTYPE required for maximum email client compatibility:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="ko">
  ...
</html>

Related Packages

License

MIT — buchida.com