Convert your Base64-Encoded Data URI's in <img> tags to Amazon S3/CloudFront URL's

Usage no npm install needed!

<script type="module">
  import nodemailerBase64ToS3 from '';



build status code coverage code style styled with prettier made with lass license

Convert your base64 encoded data URI's in <img> tags to Amazon S3/CloudFront URL's

It's the perfect alternative to cid-based embedded images!

Table of Contents


Tip: This package is bundled with Lad and already pre-configured for you.

  • Converts <img> tags with base64 encoded data URI's to absolute paths stored on S3 (or optionally CloudFront).
  • Supports all standard data URI image types (PNG, JPEG, GIF, SVG)
  • Converts SVG images to PNG images using Lipo (since SVG doesn't render in all email clients)
  • Checks Amazon S3 bucket before uploading images to prevent a redundant double-upload of the same file (better performance)
  • Uses rev-hash to prevent asset naming collisions in your S3 bucket (and to avoid Gmail image cache issues).
  • Encodes your images using gzip so your downloads are compressed and faster (uses zlib.gzip) via zlib.
  • Perfect alternative to cid embedded images.
  • Built for Lad and font-awesome-assets.



npm install nodemailer-base64-to-s3


yarn add nodemailer-base64-to-s3


const base64ToS3 = require('nodemailer-base64-to-s3');
const nodemailer = require('nodemailer');

const transport = nodemailer.createTransport({
  // pass some options here to create a transport
  // this example simply shows a JSONTransport type
  // <>
  jsonTransport: true
transport.use('compile', base64ToS3(options));


Accepts the following arguments and returns a Nodemailer plugin.

  • options (Object) - configuration options for base64ToS3
    • maxAge (Number) - Cache-Control headers max-age value in milliseconds (defaults to 1 year = 31557600000)
    • dir (String) - Amazon S3 directory inside of aws.params.Bucket to upload assets to (defaults to / (root) - must end with a trailing forward slash /) – if you want to upload to a particular folder in a bucket, then set it here
    • cloudFrontDomainName (String) - Amazon CloudFront domain name (e.g. (will use process.env.AWS_CLOUDFRONT_DOMAIN environment variable by default if available)
    • aws (Object) Required - configuration options for Amazon Web Services
      • params (Object) Required
        • Bucket (String) Required - AWS Bucket Name
    • fallbackDir (String) - a fallback directory to write to in case Amazon S3 upload fails (automatically set to os.tmpdir() otherwise if NODE_ENV is production then it is set to false and disabled) - you may want to specify the full path to your build directory so files are stored there (e.g. fallbackDir: path.join(__dirname, 'build', 'img', 'nodemailer'))
    • fallbackPrefix (String or Boolean) - the prefix to use for relative paths, e.g. you don't want to have file:///some/tmp/dir/foo.png, but you want to have instead - so specify that prefix here (e.g. fallbackPrefix: 'http://localhost:3000/img/nodemailer/' if you have a build directory fallbackDir of path.join(__dirname, 'build', 'img', 'nodemailer') and path.join(__dirname, 'build') is being served by your web server). The default value is false and therefore file:/// relative path will be used instead.
    • logger (Object) - a logger to use in the event of an error while uploading to S3 (defaults to console)

Gmail Example

This is a screenshot taken directly from Gmail on a Retina-supported device.

Above we have a Lad sample email sent using Nodemailer and Nunjucks.

What does it look like behind the scenes?

Here's a snippet from the navbar shown in the screenshot above. We utilize font-awesome-assets and nunjucks-highlight.js for rendering the icons/images and code block.

<div class="container header p-y-1">
    <ul class="nav nav-pills pull-xs-right">
      <li class="nav-item"><a title="Book" class="btn btn-md btn-outline-secondary" href="{{ config.urls.web }}/{{ locale }}">{{ fa.png2x('book', '#ccc', 20, 20, [ [ 'class', 'fa-img' ] ]) | safe }}<span class="hidden-sm-down"> {{ t('Book') }}</span></a></li>
      <li class="nav-item"><a title="Jobs" class="btn btn-md btn-outline-secondary" href="{{ config.urls.web }}/{{ locale }}/jobs">{{ fa.png2x('briefcase', '#ccc', 20, 20, [ [ 'class', 'fa-img' ] ]) | safe }}<span class="hidden-sm-down"> {{ t('Jobs') }}</a></a></li>
      <li class="nav-item"><a title="GitHub" class="btn btn-md btn-outline-secondary" href="">{{ fa.png2x('github', '#ccc', 20, 20, [ [ 'class', 'fa-img' ] ]) | safe }}<span class="hidden-sm-down"> GitHub</span></a></li>
  <h1 class="m-b-0 h4"><a class="text-muted" href="{{ config.urls.web }}/{{ locale }}">{{ 'crocodile' | emoji }}<span class="hidden-sm-down"> Lad</span></a></h3>


Name Website
Nick Baugh


MIT © Nick Baugh