The mail plugin wraps itself over the nodemailer module to send out HTML templates. For the best experience, it should be used with the render-plugin, in order to define SWIG templates, render them dynamically and apply inline styling to them.

Installation and usage
# install the plugin
npm i --save thorin-plugin-mail@1.x
# install your preferred nodemailer transport, eg. mailgun
npm i --save nodemailer-mailgun-transport@1.x

'use strict';
// app.js entry file
const thorin = require('thorin');

thorin.addPlugin(require('thorin-plugin-mail'));   // <-- add this line => {});

# run to setup folder structure
node app.js
Default configuration
  • transportarray(string)an array of transport names to use. If sent as strings, we will do a require() for the modules, otherwise, we will consider the actual object as the transport.
  • optionsobject an object of {transportKey:{transportOptions}}. If you use only one transport, it will use the direct options object.
  • fromstringgeneric from e-mail address
  • templatesstring, app/emailsthe swig e-mail template path, relative to thorin.root
  • renderstring, renderthe name of the thorin render plugin.
  • enabledboolean, truesetting this to false will disable e-mail sending and just mock send.
'use strict';
// File: config/app.js
module.exports = {
   "": {
      "transport": "mailgun",
         "options": {
         "from": "John Doe <>",
         "auth": {
            "domain": "",
            "api_key": "YOUR_API_KEY"
Plugin functionality
pluginObj.prepare(opt, vars) : Promise
Prepares the given HTML or template, to be rendered, styled and parsed.
  • optstring if a string, the plain HTML to be prepared
  • optobject if an object, should contain html or template keys.
  • varsobjectadditional variables to send when using with template
'use strict';
const pluginObj = thorin.plugin('mail');
   .alias('GET', '/preview/:template')
      template: dispatcher.validate('STRING')
   .use((intentObj, next) => {
         .prepare(intentObj.input('template'), intentObj.rawInput)
         .then((html) => {
pluginObj.send(opt, vars) : Promise
Send out custom e-mails to the given user. It will use the prepare() function to prepare the HTML, and use the specified transport to send out the e-mail.
  • opt.toemail the email to send to
  • opt.fromemailthe from e-mail, defaults to the configured one.
  • opt.from_namestringthe name in the from e-mail, default to the configured one.
  • opt.subjectstringthe email subject
  • opt.htmlstringthe HTML text to send OR
  • opt.templatestringthe template path to render and use the output as the send html.
  • opt.textboolean, trueshould we generate a text version of the email.
  • replyToemailthe reply-to e-mail
  • transportstringthe transport to use, defaults to the first one available.
'use strict';
const mailObj = thorin.plugin('mail');
    to: dispatcher.validate('EMAIL').error('INVALID_EMAIL', 'Invalid to e-mail address'),
    subject: dispatcher.validate('STRING').default(null),
    template: dispatcher.validate('STRING').error('INVALID_TEMPLATE', 'Missing template'),
    params: dispatcher.validate('JSON').default({})
  .use((intentObj, next) => {
    let data = intentObj.input();
        subject: data.subject,
        template: data.template
      }, data.params)
      .then(() => {`Sent e-mail [${data.template}] to [${}]`);
      .catch((e) => {
        log.warn(`Failed to send e-mail [${data.template}] to [${}]`);

The plugin also registeres a custom middleware mail#preview which you can use to preview your e-mail templates in a development environment.

'use strict';
if (thorin.env === 'development') {
   .alias('GET', '/mail/preview')
   // access /mail/preview?template=your/template.swig
Do you have a question or is something missing?

You can always create a new issue on GitHub or contact one of the core founders by chat.