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

react-to-handlebars

v0.1.3

Published

Convert React components to Handlebars templates

Downloads

302

Readme

react-to-handlebars

Convert React components to Handlebars templates. Write email (or other) templates in React/JSX with Handlebars.If, Handlebars.Each, and Handlebars.Val; run the CLI to emit .handlebars files you can use with any Handlebars-based stack.

Why?

The email provider I use for a certain project (Mandrill) only accepts Handlebars templates, but I wanted to author emails in React (e.g. with React Email) for a better developer experience: components, reusability, TypeScript, and a live preview. This package lets you build templates in React and compile them to Handlebars so they work with Mandrill (or any Handlebars-based handler).

Install

npm install react-to-handlebars

Peer dependency: React (^18 or ^19).

CLI

Build all .tsx / .jsx files in a directory to .handlebars files (output next to sources):

npx react-to-handlebars <dir>

Example:

npx react-to-handlebars source/emails
  • dir is resolved relative to the current working directory.
  • Each component file can export optional PreviewProps for the build (placeholder data when rendering to static HTML).

Preview (Handlebars → HTML)

Compile .handlebars templates with JSON data to static HTML for previews. For each template, the script looks for a matching JSON file (same path with .json suffix, or same base name with .json):

npx react-to-handlebars-preview <sourceDir> [outputDir]
  • sourceDir — directory containing .handlebars files (required).
  • outputDir — where to write .html files (default: previews).

Example: npx react-to-handlebars-preview source/emails previews reads source/emails/welcome.handlebars and source/emails/welcome.handlebars.json (or welcome.json) and writes previews/welcome.html.

Library usage

Use the Handlebars helpers in your React components so the build can turn them into Handlebars blocks and variables.

Setup

Wrap your template tree with Handlebars.Provider and pass the data you use in conditions and variables (for React preview only; the build uses PreviewProps or markers):

import { Handlebars } from "react-to-handlebars";

const previewData = { name: "Jane", items: [{ title: "Hello" }] };

<Handlebars.Provider data={previewData}>
  <MyEmail />
</Handlebars.Provider>;

API

| Component | Handlebars equivalent | Purpose | | ----------------- | ------------------------- | -------------------------------- | | Handlebars.If | {{#if condition}} | Conditional block | | Handlebars.Else | {{else}} | Else branch (child of If) | | Handlebars.Each | {{#each array}} | Loop over an array | | Handlebars.Val | {{path}} / {{this.x}} | Output a variable (path or name) |

  • Conditions in Handlebars.If are strings: "order.id", "items.length", "a && b", "x \|\| y", "!flag". They are evaluated against the Provider data in React and turned into Handlebars {{#if ...}} at build time.
  • Each: array is the Handlebars path (e.g. "items"). Optional itemVar gives the block param name (e.g. "item"{{#each items as \|item\|}}). Inside Each, Handlebars.Val with name="title" becomes {{this.title}}.
  • Val: name is the Handlebars path (or property name inside an each). Optional value is used in React preview when not building.

Example component

import { Handlebars } from "react-to-handlebars";

export const PreviewProps = {
  userName: "Alex",
  items: [{ label: "First" }, { label: "Second" }],
};

export default function MyEmail() {
  return (
    <div>
      <p>
        Hello, <Handlebars.Val name="userName" value="Alex" />.
      </p>
      <Handlebars.If condition="items.length">
        <ul>
          <Handlebars.Each array="items" itemVar="item">
            <li>
              <Handlebars.Val name="label" />
            </li>
          </Handlebars.Each>
        </ul>
        <Handlebars.Else>
          <p>No items.</p>
        </Handlebars.Else>
      </Handlebars.If>
    </div>
  );
}

After running react-to-handlebars on the directory containing this file, you get a .handlebars file with classic Handlebars {{#if}}, {{#each}}, {{variable}}, and {{else}}.

License

MIT