{"id":50833588,"url":"https://github.com/heysupertape/react-email-rails","last_synced_at":"2026-06-14T02:00:37.118Z","repository":{"id":361659410,"uuid":"1253829373","full_name":"heysupertape/react-email-rails","owner":"heysupertape","description":"Build and send emails using React and Rails","archived":false,"fork":false,"pushed_at":"2026-06-09T17:50:27.000Z","size":566,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T19:18:11.008Z","etag":null,"topics":["action-mailer","email","email-templates","rails","react","react-email","ruby-on-rails"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/heysupertape.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-29T21:22:00.000Z","updated_at":"2026-06-09T17:50:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/heysupertape/react-email-rails","commit_stats":null,"previous_names":["heysupertape/react-email-rails"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/heysupertape/react-email-rails","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heysupertape%2Freact-email-rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heysupertape%2Freact-email-rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heysupertape%2Freact-email-rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heysupertape%2Freact-email-rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/heysupertape","download_url":"https://codeload.github.com/heysupertape/react-email-rails/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heysupertape%2Freact-email-rails/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34306772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["action-mailer","email","email-templates","rails","react","react-email","ruby-on-rails"],"created_at":"2026-06-14T02:00:19.177Z","updated_at":"2026-06-14T02:00:37.091Z","avatar_url":"https://github.com/heysupertape.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"![react-email-rails](react-email-rails.png)\n\n# react-email-rails\n\nBuild and send emails using React and Rails with [React Email](https://react.email) and [Action Mailer](https://guides.rubyonrails.org/action_mailer_basics.html).\n\n## Contents\n\n- [Why](#why)\n- [How](#how)\n- [Status](#status)\n- [Requirements](#requirements)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n- [Configuration](#configuration)\n- [Deployment](#deployment)\n- [Development](#development)\n- [Contributing](#contributing)\n- [Security](#security)\n- [License](#license)\n\n## Why\n\nBuilding HTML emails is painfully archaic. [React Email](https://react.email) brings React, Tailwind, and TypeScript to email templates. This gem wires it into Action Mailer so React components deliver as generated HTML and text emails.\n\n## How\n\n**In development,** the gem renders components live through Vite's dev pipeline, so your emails get the same module resolution and transforms as the rest of your frontend.\n\n**In production,** Rails builds a server-side renderer bundle during `assets:precompile` using `reactEmailRails()` in your Vite config for discovery and options.\n\nreact-email-rails automatically renders both HTML and plain-text versions from the same component. Delivery, headers, previews, queues, and callbacks all stay normal Action Mailer. If rendering fails, no email is sent and `ReactEmailRails::RenderError` is raised.\n\n## Status\n\n**react-email-rails is pre-1.0.** It was extracted from [XOXO](https://xoxo.email) which is pre-launch, so it hasn't been battle-tested in high-volume production environments yet. It's tested in CI across the supported Ruby, Rails, Node, and Vite versions, but the API may still change before 1.0. Please [share feedback and report issues](https://github.com/heysupertape/react-email-rails/issues).\n\n## Requirements\n\n- Ruby \u003e= 3.3\n- Action Mailer, Active Support, and Railties \u003e= 7.1 and \u003c 9.0\n- Node \u003e= 20.19\n- Vite 7 or 8\n- React 18 or 19\n- `@react-email/render` 2.x\n\n\u003e We recommend [rails_vite](https://github.com/skryukov/rails_vite/) for Vite with Rails.\n\n## Quick Start\n\nAdd the gem:\n\n```ruby\n# Gemfile\n\ngem \"react-email-rails\"\n```\n\n### Automatic Install\n\nRun the installer:\n\n```sh\nbin/rails generate react_email_rails:install\n```\n\nThis creates `config/initializers/react_email_rails.rb`, installs missing JavaScript dependencies when it can detect your package manager, adds `reactEmailRails()` to `vite.config.*`, and creates `app/javascript/emails`.\n\nThe installed setup then follows the normal Rails lifecycle:\n\n- `bin/rails generate react_email_rails:email ...` creates matching mailers and React components.\n- `bin/dev` renders through Vite on demand.\n- `bin/rails assets:precompile` builds the production renderer bundle automatically.\n- `bin/rails react_email_rails:build` builds the bundle directly when CI or tests need it.\n\n### Manual Install\n\nInstall the npm package and peer dependencies manually:\n\n```sh\nnpm i react-email-rails @react-email/render @react-email/components react react-dom\n```\n\nUpdate your Vite config to add the plugin:\n\n```ts\n// vite.config.ts\n\nimport { defineConfig } from \"vite\"\nimport { reactEmailRails } from \"react-email-rails\"\n\nexport default defineConfig({\n  plugins: [reactEmailRails()],\n})\n```\n\n### Your First Email\n\nGenerate a mailer and React Email component:\n\n```sh\nbin/rails generate react_email_rails:email Account welcome\n```\n\nThe generator follows Rails' mailer generator shape: `NAME [method method]`. It creates the mailer, matching React components, a mailer preview, and a test. It reads `emails.path` and `emails.extension` from `reactEmailRails()` when available. Pass flags to override them:\n\n```sh\nbin/rails generate react_email_rails:email Account welcome --emails-path=app/emails --extension=jsx\n```\n\nEdit the generated mailer to pass any necessary props:\n\n```ruby\nclass AccountMailer \u003c ApplicationMailer\n  def welcome\n    account = params.fetch(:account)\n\n    mail(\n      to: account.email,\n      subject: \"Welcome\",\n      react: {\n        account: {\n          name: account.name,\n        },\n      },\n    )\n  end\nend\n```\n\nEdit the generated email component:\n\n```tsx\n// app/javascript/emails/account_mailer/welcome.tsx\n\nimport { Body, Container, Html, Text } from \"@react-email/components\"\n\ntype WelcomeProps = {\n  account: {\n    name: string\n  }\n}\n\nexport default function Welcome({ account }: WelcomeProps) {\n  return (\n    \u003cHtml\u003e\n      \u003cBody\u003e\n        \u003cContainer\u003e\n          \u003cText\u003eWelcome, {account.name}\u003c/Text\u003e\n        \u003c/Container\u003e\n      \u003c/Body\u003e\n    \u003c/Html\u003e\n  )\n}\n```\n\n\u003e [@react-email/components](https://react.email/docs/components/html) provides primitives like `\u003cButton\u003e`, `\u003cHeading\u003e`, `\u003cTailwind\u003e`, and more.\n\nThat's it. It now renders and delivers like any other Action Mailer email.\n\n## Usage\n\nPass data from your mailer and each top-level key becomes a prop on the component's default export. Our API mirrors [inertia-rails](https://inertia-rails.dev), making the two libraries feel consistent when used together.\n\n```ruby\nmail react: { foo: \"bar\" }, ...\n```\n\n```tsx\nexport default function Email({ foo }: { foo: string }) {\n  // ...\n}\n```\n\n### Props\n\nChoose the level of inference you want for your props:\n\n#### Implicit Component, Instance Props\n\n```ruby\nclass AccountMailer \u003c ApplicationMailer\n  use_react_instance_props\n\n  def welcome\n    @account = params.fetch(:account)\n    mail react: true, to: @account.email, subject: \"Welcome\"\n  end\nend\n```\n\nAction Mailer's framework assigns (including `params` and `rendered_format`) are excluded from instance props.\n\nWithout `use_react_instance_props`, `react: true` still infers the component and renders it with no props, which is handy for emails that take no props at all.\n\n#### Implicit Component, Explicit Props\n\n```ruby\nmail(\n  ...\n  react: {\n    account: {\n      name: account.name,\n    },\n  },\n)\n```\n\n#### Explicit Component, Explicit Props\n\n```ruby\nmail(\n  ...\n  react: \"accounts/welcome\",\n  props: {\n    account: {\n      name: account.name,\n    },\n  },\n)\n```\n\n### Shared Props\n\nUse `react_email_share` to share data with all of a mailer's emails and subclasses, and it'll be automatically merged with any inline props.\n\n```ruby\nclass MarketingMailer \u003c ApplicationMailer\n  # Static value\n  react_email_share app_name: \"Acme\"\n\n  # Lambda value, evaluated lazily in the mailer instance\n  react_email_share unread_count: -\u003e { current_user\u0026.unread_count }\n\n  # Block, evaluated lazily in the mailer instance\n  react_email_share do\n    { brand: { name: \"Acme\", url: marketing_url } }\n  end\nend\n```\n\nPer-mail props win over shared props of the same name, so a mailer can always override what it inherits:\n\n```ruby\nmail react: { app_name: \"Acme Pro\" }, ... # overrides the shared app_name\n```\n\nShared props apply to all three forms above (`react:` hash, `react: \"component\", props:`, and `react: true`).\n\n#### Conditional Sharing\n\nPass any `before_action` filter (`only`, `except`, `if`, `unless`) to scope a share to certain actions:\n\n```ruby\nreact_email_share only: [:welcome, :reactivation] do\n  { promotion: current_promotion }\nend\n\nreact_email_share if: :user_signed_in? do\n  { user: { name: current_user.name } }\nend\n```\n\nYou can also share from inside an action, before calling `mail`:\n\n```ruby\ndef welcome\n  react_email_share notice: \"Thanks for joining!\"\n  mail react: { account: }, to: account.email, subject: \"Welcome\"\nend\n```\n\n#### Deep Merging\n\nBy default shared props are merged shallowly, so a per-mail prop replaces a shared one of the same name outright. Pass `deep_merge: true` to merge nested hashes instead:\n\n```ruby\nreact_email_share do\n  { settings: { theme: \"light\", locale: \"en\" } }\nend\n\n# Shallow (default): settings =\u003e { theme: \"dark\" }\nmail react: { settings: { theme: \"dark\" } }, ...\n\n# Deep: settings =\u003e { theme: \"dark\", locale: \"en\" }\nmail react: { settings: { theme: \"dark\" } }, deep_merge: true, ...\n```\n\nSet `config.deep_merge_shared_props = true` to make deep merging the default for every email. (See [Configuration](#configuration))\n\n### Prop Serialization\n\nLike `render json:`, `mail react:` accepts any object that responds to `as_json`, including hashes, Active Model objects, and serializers such as [Alba](https://github.com/okuramasafumi/alba) or [ActiveModel::Serializer](https://github.com/rails-api/active_model_serializers).\n\n### Prop Transformation\n\nProp keys are camelized by default, so `account.plan_name` arrives as `account.planName`. Override `transform_props` in your [configuration](#configuration).\n\n### Component Names\n\nComponent names are inferred from the mailer and action:\n\n| Mailer action | Component |\n|---------------|-----------|\n| `AccountMailer#welcome` | `account_mailer/welcome` |\n| `Users::InviteMailer#new_invite` | `users/invite_mailer/new_invite` |\n\nRails derives `account_mailer` from `AccountMailer` via `mailer_name`. By default, `account_mailer/welcome` resolves to `app/javascript/emails/account_mailer/welcome.tsx` or `.jsx`.\n\nFiles and directories starting with `_` are ignored as renderable email entries by default. Use them for shared components such as `_components/email_layout.tsx`. They can still be imported by email components.\n\nOverride the inferred name per mail:\n\n```ruby\nmail react: \"users/welcome\", props: { user: }, to:, subject:\n```\n\nOr override `component_path_resolver` globally in your [configuration](#configuration).\n\n### Layouts\n\nAction Mailer layouts aren't applied to `react:` emails. React Email treats layouts like any other component, so share structure with normal React composition instead:\n\n```tsx\n// app/javascript/emails/_components/email_layout.tsx\n\nimport { Body, Container, Html } from \"@react-email/components\"\nimport type { ReactNode } from \"react\"\n\ntype EmailLayoutProps = {\n  children: ReactNode\n}\n\nexport function EmailLayout({ children }: EmailLayoutProps) {\n  return (\n    \u003cHtml\u003e\n      \u003cBody\u003e\n        \u003cContainer\u003e{children}\u003c/Container\u003e\n      \u003c/Body\u003e\n    \u003c/Html\u003e\n  )\n}\n```\n\n```tsx\n// app/javascript/emails/account_mailer/welcome.tsx\n\nimport { Text } from \"@react-email/components\"\nimport { EmailLayout } from \"../_components/email_layout\"\n\nexport default function Welcome() {\n  return (\n    \u003cEmailLayout\u003e\n      \u003cText\u003eWelcome\u003c/Text\u003e\n    \u003c/EmailLayout\u003e\n  )\n}\n```\n\nSee [Component Names](#component-names) for how shared `_` files are handled.\n\n### Editor\n\nIf you're also using [@react-email/editor](https://react.email/docs/editor) to let users compose emails inside your app, `ReactEmailRails.compose` can render those stored documents on the server.\n\nSee [Editor rendering](docs/editor.md) for setup and usage.\n\n## Configuration\n\nConfiguration is handled primarily on the Rails side, though there are some Vite options to be aware of.\n\n### Rails Configuration\n\nIf the defaults don't fit, override them in `config/initializers/react_email_rails.rb`:\n\n| Option | Default |\n|--------|---------|\n| `component_path_resolver` | `-\u003e(mailer:, action:) { \"#{mailer}/#{action}\" }` |\n| `transform_props` | `:lower_camel` |\n| `render_mode` | `:subprocess` |\n| `render_options` | `{}` |\n| `render_timeout` | `10` seconds |\n| `render_process_max_requests` | `1_000` |\n| `on_render_error` | `nil` |\n| `deep_merge_shared_props` | `false` |\n\n#### Prop Transformation\n\nSet `transform_props` to another supported value if you prefer a different prop key style:\n\n| Value | Example |\n|-------|---------|\n| `:camel` | `AccountName` |\n| `:lower_camel` (default) | `accountName` |\n| `:dash` | `account-name` |\n| `:snake` | `account_name` |\n| `:none` | preserves serialized keys |\n\n```ruby\nReactEmailRails.configure do |config|\n  config.transform_props = :none\nend\n```\n\n`transform_props` only controls prop key names. Props are always serialized with `as_json`.\n\n#### Render Modes\n\n`:subprocess` starts a fresh Node process for each render. It's simple, isolated, and always uses the latest bundle, but pays Node startup and bundle load each time.\n\n`:persistent` reuses one long-lived Node process per worker. It's faster for render-heavy workers, but uses more memory and can serve a stale component until recycled. The default `:subprocess` mode is usually enough. Switch when Node startup shows up in traces or batch jobs render many emails from the same bundle.\n\nEnable persistent mode for render-heavy worker processes:\n\n```ruby\nReactEmailRails.configure do |config|\n  config.render_mode = :persistent\nend\n```\n\nPersistent mode keeps one Node child per process:\n\n- Renders are newline-delimited JSON and processed one at a time. Scale throughput with more worker processes.\n- It's fork-safe: under clustered Puma or forking job runners, each worker spawns its own child.\n- The child is recycled after `render_process_max_requests` renders to bound memory growth. Set it to `nil` to disable recycling.\n\n#### Render Options\n\n`render_options` is passed to [@react-email/render](https://react.email/docs/utilities/render). Use `html` and `text` keys for each output. Option keys are camelized before they cross into JavaScript.\n\n```ruby\nReactEmailRails.configure do |config|\n  config.render_options = {\n    html: {\n      pretty: Rails.env.development?\n    },\n    text: {\n      html_to_text_options: {\n        selectors: [{ selector: \"img\", format: \"skip\" }],\n      },\n    },\n  }\nend\n```\n\n#### Error Reporting\n\nUse `on_render_error` to report failures before the exception is re-raised. The callback receives the error plus `kind:` and `component:`:\n\n```ruby\nReactEmailRails.configure do |config|\n  config.on_render_error = -\u003e(error, **context) {\n    Rails.error.report(error, context:)\n  }\nend\n```\n\n#### Instrumentation\n\nEvery render emits `render.react-email-rails` through [ActiveSupport::Notifications](https://guides.rubyonrails.org/active_support_instrumentation.html). The payload includes `kind`, `component`, and successful HTML size in `html_bytes`:\n\n```ruby\nActiveSupport::Notifications.subscribe(\"render.react-email-rails\") do |event|\n  Rails.logger.info(\"[react-email-rails] Rendered #{event.payload[:component]} (Duration: #{event.duration.round}ms | Size: #{event.payload[:html_bytes]} bytes)\")\nend\n```\n\n### Vite Configuration\n\nMost apps only need the `reactEmailRails()` plugin from [Quick Start](#quick-start). The options below change component discovery, bundle dependency handling, and isolated renderer transforms.\n\nIn development and production, the isolated renderer loads `reactEmailRails()`, JSX support, and component-facing Vite config such as `resolve`, `define`, `css`, `json`, `assetsInclude`, `esbuild`, and `oxc`. It doesn't load your other app plugins. Server, preview, dependency optimization, and build output settings stay owned by react-email-rails.\n\n#### Plugin Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `emails.path` | `\"app/javascript/emails\"` | Directory containing email components |\n| `emails.extension` | `[\".tsx\", \".jsx\"]` | Component extension, or an array of extensions |\n| `emails.ignore` | `[\"**/_*\", \"**/_*/**\"]` | Glob patterns ignored under `emails.path` |\n| `standalone` | `true` | Inline production renderer bundle dependencies |\n| `vite` | `{}` | Extra email-only Vite config for compilation and resolution |\n\nUse a custom directory:\n\n```ts\nreactEmailRails({\n  emails: \"app/emails\",\n})\n```\n\nUse multiple extensions:\n\n```ts\nreactEmailRails({\n  emails: {\n    extension: [\".email.tsx\", \".email.jsx\"],\n  },\n})\n```\n\nComponent names come from the Vite directory layout (see [Component Names](#component-names)). To map mailer actions to a different layout, override `component_path_resolver` on the Ruby side rather than renaming in the plugin, so both halves stay in sync.\n\n#### Advanced: Email-Only Vite Plugins\n\nMost apps don't need extra email plugins. If email components need a transform that isn't part of Vite's default pipeline, add that transform to the isolated renderer:\n\n```ts\nimport mdx from \"@mdx-js/rollup\"\nimport { defineConfig } from \"vite\"\nimport { reactEmailRails } from \"react-email-rails\"\n\nexport default defineConfig({\n  plugins: [\n    reactEmailRails({\n      vite: {\n        plugins: [mdx()],\n      },\n    }),\n  ],\n})\n```\n\nThese `vite` options are used by `react-email-rails-dev` and `react-email-rails-build`. Only `assetsInclude`, `css`, `define`, `esbuild`, `json`, `oxc`, `plugins`, and `resolve` are accepted. Output settings such as `build.outDir` and `build.rollupOptions` are ignored so Ruby can always find the bundle.\n\n#### Standalone Builds\n\nBy default the production renderer bundle inlines React, `@react-email/render`, and other Node dependencies. This works well for Rails deploys that build assets in one stage and run without `node_modules` in the final image. Development previews keep dependencies external, even when `standalone` is enabled.\n\nSet `standalone: false` when your runtime already ships `node_modules` and you prefer a smaller SSR-style bundle:\n\n```ts\nreactEmailRails({\n  standalone: false,\n})\n```\n\nExternalized bundles are smaller and may build faster, but the renderer needs the externalized packages available at runtime.\n\n## Deployment\n\nFor production deploys, run the normal Rails asset task:\n\n```sh\nbin/rails assets:precompile\n```\n\nThe `react_email_rails:build` task is hooked into `assets:precompile` automatically. It loads `reactEmailRails()` options from your Vite config, then writes `tmp/react-email-rails/emails.js` with the email component registry. If [Editor document rendering](docs/editor.md) is enabled, the bundle also includes document renderers.\n\nYou can run it directly when needed:\n\n```sh\nbin/rails react_email_rails:build\n```\n\nProduction rendering runs that bundle with Node. Set `SKIP_REACT_EMAIL_RAILS_BUILD=1` to skip the automatic asset hook. Directly running `bin/rails react_email_rails:build` always attempts the build.\n\nThe npm package, Vite, React, and `@react-email/render` must be available when Rails runs `assets:precompile`. If you enable [Editor document rendering](docs/editor.md), its peer dependencies must be available too.\n\nThe bundle is required, not an optimization. If it's missing, renders raise `ReactEmailRails::RenderError`. Action Mailer deliveries aren't sent.\n\nThe Ruby gem and npm package must stay on the same version. The renderer includes a small protocol/version handshake, so mismatched installs fail with an actionable `ReactEmailRails::RenderError` instead of silently returning malformed output.\n\nThe build command preserves `emails.path`, `emails.extension`, `emails.ignore`, `standalone`, and email-only `vite` options.\n\n### Renderer Verification\n\nTo confirm the renderer is ready before relying on it, run:\n\n```sh\nbin/rails react_email_rails:verify\n```\n\nIt checks that the render command runs and that the npm package version matches the gem, then exits non-zero with an actionable message on failure. Wire it into CI or release steps to catch missing bundles or version drift before the first render.\n\nFor programmatic checks (for example, a health endpoint), `ReactEmailRails.healthy?` returns a boolean. If you specifically want a check at boot, call it from your own initializer and scope it to the processes that send mail so others don't pay the cost:\n\n```ruby\nRails.application.config.after_initialize do\n  if Rails.env.production? \u0026\u0026 Sidekiq.server? \u0026\u0026 !ReactEmailRails.healthy?\n    Rails.logger.error(\"[react-email-rails] renderer verification failed\")\n  end\nend\n```\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for local setup, checks, formatting, and release verification.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub. See [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.\n\n## Security\n\nPlease report vulnerabilities privately. See [SECURITY.md](SECURITY.md) for details.\n\n## License\n\nThe gem and npm package are available as open source under the terms of the [MIT License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheysupertape%2Freact-email-rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fheysupertape%2Freact-email-rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheysupertape%2Freact-email-rails/lists"}