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-email-viewer

v1.1.0

Published

Production-ready React component for rendering Outlook (.msg) and RFC822 (.eml) emails — Base64, Blob, File, ArrayBuffer, URL, attachments, themes, and search.

Readme

react-email-viewer

Introduction

react-email-viewer is a production-ready React component for rendering Microsoft Outlook (.msg) and RFC822 (.eml) emails in modern web apps.

Pass Base64, binary, Blob, File, ArrayBuffer, Uint8Array, Response, or a URL — get an Outlook/Gmail-style preview with headers, HTML/text body, attachments, themes, and search.

import { EmailViewer } from 'react-email-viewer';
import 'react-email-viewer/styles.css';

<EmailViewer source={base64OrFileOrBuffer} />;

Works with TypeScript and JavaScript (ESM + CommonJS + .d.ts).

Why this package exists

Enterprise backends often deliver emails as opaque payloads. Teams reinvent decoding, MIME parsing, CID image rewriting, and UI chrome. react-email-viewer standardizes that path with a typed, accessible, themeable React surface.

Installation

npm install react-email-viewer

Peer dependencies: react and react-dom ≥ 18.

# styles (required for default UI)
import "react-email-viewer/styles.css";

Requires Node.js 18+ for tooling; the viewer runs in modern browsers.

Features

  • .eml (RFC822) and .msg (Outlook)
  • Sources: Base64, binary string, Blob, File, ArrayBuffer, Uint8Array, Response, URL
  • Subject, From/To/Cc/Bcc/Reply-To, Date, Priority, Categories, Headers
  • HTML + plain text bodies
  • Attachments with download + preview (images/PDF/text)
  • CID / inline / embedded image rewriting
  • Light / Dark / Auto themes via CSS variables
  • Toolbar: search, zoom, theme, headers, copy, print, download
  • Accessible toolbar + landmarks
  • Tree-shakeable exports of subcomponents + parseEmail / useEmail

Quick Start

TypeScript

import { EmailViewer } from 'react-email-viewer';
import 'react-email-viewer/styles.css';

export function App({ payload }: { payload: string }) {
  return (
    <EmailViewer
      source={payload}
      theme="auto"
      onLoad={(email) => console.log(email.subject)}
      onError={(err) => console.error(err)}
    />
  );
}

JavaScript

import { EmailViewer } from 'react-email-viewer';
import 'react-email-viewer/styles.css';

export function App({ file }) {
  return <EmailViewer source={file} theme="light" />;
}

From URL / API

<EmailViewer url="/api/emails/123.eml" />

File upload

<input
  type="file"
  accept=".eml,.msg"
  onChange={(e) => setFile(e.target.files?.[0] ?? null)}
/>
<EmailViewer source={file} />

API Reference

<EmailViewer />

| Prop | Type | Default | Description | | ----------------------------- | ----------------------------------------------------------------- | -------- | ------------------------------- | | source | string \| Blob \| File \| ArrayBuffer \| Uint8Array \| Response | — | Email payload | | url | string | — | Fetch email via GET | | format | "eml" \| "msg" \| "auto" | "auto" | Force parser | | theme | "light" \| "dark" \| "auto" | "auto" | Color theme | | renderMode | "html" \| "text" \| "auto" | "auto" | Body mode | | showToolbar | boolean | true | Toolbar visibility | | showAttachments | boolean | true | Attachment list | | allowExternalImages | boolean | false | Allow remote <img> (off by default) | | zoom | number | 100 | Initial zoom % | | hideBcc | boolean | false | Hide BCC row | | onLoad | (email) => void | — | Parsed callback | | onError | (error) => void | — | Error callback | | onDownloadAttachment | (att) => void | — | Download hook | | className / style | — | — | Root customization | | emptyLabel / loadingLabel | string | — | Status copy |

parseEmail(options) / parseEml / parseMsg

Headless parsing without UI.

useEmail({ source, url, format })

Hook returning { email, loading, error }.

Subcomponents

EmailHeader, EmailToolbar, EmailBody, EmailAttachmentList, AttachmentCard, EmailAddress, EmailDate, EmailPriority, EmailBadge, EmailMetadata.

Examples

Base64

<EmailViewer source={base64String} />

ArrayBuffer

const buf = await file.arrayBuffer();
<EmailViewer source={buf} />;

Next.js (App Router)

'use client';
import { EmailViewer } from 'react-email-viewer';
import 'react-email-viewer/styles.css';

Mark the importing module as a Client Component — the package ships a "use client" banner for bundlers that honor it.

Advanced Examples

Custom theme via CSS variables

.my-email {
  --rev-accent: #0f766e;
  --rev-bg: #f8fafc;
  --rev-radius: 14px;
}
<EmailViewer className="my-email" theme="light" source={source} />

Headless parse + custom UI

const email = await parseEmail({ source: bytes, format: 'eml' });

Block external images

<EmailViewer source={source} allowExternalImages={false} />

Framework Integration

Works with React, Next.js, Vite, CRA, Remix, and Astro (client islands). Import CSS once at the app root. Prefer client-side rendering for .msg OLE parsing.

TypeScript Usage

import type {
  EmailViewerProps,
  ParsedEmail,
  EmailAttachment,
  Theme,
  RenderMode,
} from 'react-email-viewer';

Error Handling

<EmailViewer source={source} onError={(err) => toast.error(err.message)} />

Invalid MIME / corrupt MSG surfaces as a visible error region (role="alert").

Performance

  • Parse once per source/url change
  • Attachment bytes stay lazy until download/preview
  • Prefer renderMode="text" for huge HTML
  • Avoid embedding multi‑100MB attachments as Base64 strings in React state — pass Blob/File instead

Best Practices

  • Sanitize is basic (script/on* stripping); for untrusted mail consider an additional HTML sanitizer
  • Keep allowExternalImages={false} when previewing untrusted mail
  • Don’t log full email bodies in production analytics
  • Use format="msg" when filename/magic is unreliable

Security

  • HTML is lightly sanitized (scripts / inline handlers / javascript: removed)
  • External images can be blocked
  • Downloads use object URLs created in-memory

See SECURITY.md.

FAQ

Does it work without React?
Use parseEmail headlessly; UI components require React 18+.

SSR?
Parsing can run on the server for .eml. Prefer client for .msg and interactive UI.

Can I add more formats later?
Yes — parsers are isolated; contribute a new parseX + format detector.

CommonJS?
Yes: require("react-email-viewer").

Migration Guide

From hand-rolled MIME viewers

Replace custom decode + dangerouslySetInnerHTML with <EmailViewer source={…} /> and keep your layout chrome around it.

SemVer

Breaking changes only in major versions — see CHANGELOG.md.

Troubleshooting

| Symptom | Fix | | --------------------- | ------------------------------------------------------------- | | No styles | import "react-email-viewer/styles.css" | | Blank MSG | Ensure bytes are full OLE file; try format="msg" | | CID images missing | Confirm Content-ID attachments parsed; check HTML cid: refs | | Next.js window errors | Use Client Component | | Types missing | TS 5+, moduleResolution bundler/node16+ |

Browser Support

Chrome, Edge, Firefox, Safari (current evergreen). Mobile responsive layout included.

Contributing

See CONTRIBUTING.md.

License

MIT