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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@anishhs/postie

v1.0.5

Published

A simple and powerful email sending library for Node.js with CLI support

Downloads

17

Readme

📧 Postie API Documentation

👤 Author

👤 Anish Shekh

📦 Version

Current version: 1.0.5

📑 Table of Contents

  1. Installation
  2. TypeScript Support
  3. Configuration
  4. Basic Setup
  5. Core Methods
  6. Email Sending
  7. Template Support
  8. Middleware
  9. Email Triggering By Aliases
  10. CLI Usage
  11. Configuration Files
  12. Error Handling
  13. Development Mode

🚀 Installation

# Install as a dependency in your project
npm install @anishhs/postie

# Or install globally for CLI usage
npm install -g @anishhs/postie

📘 TypeScript Support

Postie comes with full TypeScript support out of the box. All features are properly typed and documented. Here's how to use Postie with TypeScript:

Basic Setup

import {
  Postie,
  SMTPConfig,
  PostieConfig,
  EmailOptions,
  AliasConfig,
  TemplateEmailOptions,
  TemplateEngine,
  Middleware,
  SendResult,
  EmailAddress,
  EmailAttachment,
  Logger
} from '@anishhs/postie';

// Create a Postie instance
const postie = new Postie();

SMTP Configuration

const smtpConfig: SMTPConfig = {
  host: 'smtp.example.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'password'
  },
  debug: true,
  logger: true
};

postie.setTransporter(smtpConfig);

Global Configuration

const postieConfig: PostieConfig = {
  devMode: false,
  retryAttempts: 3,
  retryDelay: 1000
};

postie.configure(postieConfig);

Sending Emails

// Basic email with all available options
const emailOptions: EmailOptions = {
  from: '[email protected]',
  fromName: 'Project Team',
  to: '[email protected]',
  toName: 'Recipient Name',
  cc: '[email protected]',
  ccName: 'CC Recipient',
  bcc: '[email protected]',
  bccName: 'BCC Recipient',
  subject: 'Test Email',
  text: 'This is a test email',
  html: '<p>This is a test email</p>',
  attachments: [
    {
      filename: 'test.txt',
      content: 'This is a test file content',
      contentType: 'text/plain',
      encoding: 'utf8'
    }
  ],
  headers: {
    'X-Custom-Header': 'value'
  }
};

// Multiple recipients with different formats
const multiRecipientEmail: EmailOptions = {
  from: '[email protected]',
  to: [
    '[email protected]',
    { email: '[email protected]', name: 'Team Member' }
  ],
  cc: [
    '[email protected]',
    { email: '[email protected]', name: 'CC Recipient' }
  ],
  bcc: [
    '[email protected]',
    { email: '[email protected]', name: 'BCC Recipient' }
  ],
  subject: 'Multi-recipient Email',
  text: 'This email goes to multiple recipients'
};

const result: SendResult = await postie.send(emailOptions);

Template Emails

// Template email with required fields
const templateEmail: TemplateEmailOptions = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Welcome',
  template: 'Hello {{name}}, welcome to {{company}}!',
  data: {
    name: 'John Doe',
    company: 'Example Inc'
  }
};

const templateResult: SendResult = await postie.sendTemplate(templateEmail);

Template Engine

const templateEngine: TemplateEngine = {
  compile: (template: string) => template,
  render: (compiled: unknown, data: Record<string, any>) => {
    return (compiled as string).replace(/\{\{(\w+)\}\}/g, (match: string, key: string) => data[key] || match);
  }
};

postie.setTemplateEngine(templateEngine);

Middleware

const logMiddleware: Middleware = (options: EmailOptions, next: () => void) => {
  console.log('Middleware: Preparing to send email to:', options.to);
  next();
};

postie.use(logMiddleware);

Aliases

// Define an alias with all available options
const welcomeAlias: AliasConfig = {
  type: 'notify',
  from: '[email protected]',
  fromName: 'Project Team',
  to: '[email protected]',
  toName: 'Recipient Name',
  cc: '[email protected]',
  ccName: 'CC Recipient',
  bcc: '[email protected]',
  bccName: 'BCC Recipient',
  subject: 'Welcome',
  text: 'This is a welcome email',
  html: '<p>This is a welcome email</p>',
  template: 'Hello {{name}}, welcome to {{company}}!',
  data: {
    company: 'Example Inc'
  },
  attachments: [
    {
      filename: 'welcome.pdf',
      path: '/path/to/welcome.pdf',
      contentType: 'application/pdf'
    }
  ],
  headers: {
    'X-Custom-Header': 'value'
  }
};

postie.define('welcome', welcomeAlias);

// Trigger with overrides
const result: SendResult = await postie.trigger('welcome', {
  to: '[email protected]',
  data: {
    name: 'John Doe'
  }
});

Special Email Types

// Notification with all available options
const notificationResult: SendResult = await postie.notify({
  from: '[email protected]',
  fromName: 'System',
  to: '[email protected]',
  toName: 'Admin',
  subject: 'System Notification',
  text: 'This is a notification',
  html: '<p>This is a notification</p>',
  attachments: [
    {
      filename: 'log.txt',
      content: 'System logs',
      contentType: 'text/plain'
    }
  ],
  headers: {
    'X-Priority': '1'
  }
});

// Alert with all available options
const alertResult: SendResult = await postie.alert({
  from: '[email protected]',
  fromName: 'Monitoring',
  to: '[email protected]',
  toName: 'Admin',
  subject: 'System Alert',
  text: 'This is an alert',
  html: '<p>This is an alert</p>',
  attachments: [
    {
      filename: 'error.log',
      content: 'Error logs',
      contentType: 'text/plain'
    }
  ],
  headers: {
    'X-Priority': '1'
  }
});

// Ping with all available options
const pingResult: SendResult = await postie.ping({
  from: '[email protected]',
  fromName: 'System',
  to: '[email protected]',
  toName: 'Admin',
  subject: 'Ping Test',
  text: 'Ping!',
  html: '<p>Ping!</p>',
  attachments: [
    {
      filename: 'ping.log',
      content: 'Ping logs',
      contentType: 'text/plain'
    }
  ],
  headers: {
    'X-Priority': '1'
  }
});

Error Handling

try {
  const result = await postie.send(emailOptions);
  console.log('Email sent successfully:', result);
} catch (error) {
  console.error('Failed to send email:', error);
  // Error details include:
  // - SMTP response
  // - Connection status
  // - Retry attempts
}

Development Mode

// Configure for development
postie.configure({
  devMode: true,
  retryAttempts: 1,
  retryDelay: 100
});

// Send test email
const devResult: SendResult = await postie.send({
  to: '[email protected]',
  subject: 'Test Email',
  text: 'This is a test email'
});
// Email will be logged but not sent

📧 Basic Usage

⚙️ Configuration

Postie provides flexible configuration options that can be set globally or per instance.

Global Configuration

// Configure global settings
postie.configure({
  devMode: false,      // Enable development mode
  retryAttempts: 3,    // Number of retry attempts
  retryDelay: 1000     // Delay between retries in milliseconds
})

SMTP Configuration

// Configure SMTP settings
postie.setTransporter({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'your-app-password'
  }
})

Template Engine Configuration

// Configure template engine
postie.setTemplateEngine({
  render: (template, data) => {
    // Custom template rendering logic
    return renderedTemplate
  }
})

⚙️ Basic Setup

const Postie = require('@anishhs/postie')
const postie = new Postie()

// Configure SMTP
postie.setTransporter({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false, // Use STARTTLS
  auth: {
    user: '[email protected]',
    pass: 'your-app-password'
  }
})

// Optional: Configure retry settings
postie.configure({
  retryAttempts: 3,
  retryDelay: 1000,
  devMode: false
})

🔧 Core Methods

setTransporter(config)

Configures the SMTP transporter.

postie.setTransporter({
  host: 'smtp.gmail.com',
  port: 587,
  secure: false,
  auth: {
    user: '[email protected]',
    pass: 'your-app-password'
  }
})

configure(config)

Sets global configuration options.

postie.configure({
  devMode: false,      // Enable development mode
  retryAttempts: 3,    // Number of retry attempts
  retryDelay: 1000     // Delay between retries in milliseconds
})

testConnection()

Tests the SMTP connection.

const success = await postie.testConnection()
if (success) {
  console.log('SMTP connection successful')
}

📨 Email Sending

📝 Basic Email

await postie.send({
  from: '[email protected]',
  fromName: 'John Doe', // Optional
  to: '[email protected]',
  toName: 'Jane Smith', // Optional
  subject: 'Hello',
  text: 'This is a test email'
})

👥 Multiple Recipients

await postie.send({
  from: '[email protected]',
  to: [
    '[email protected]',
    { email: '[email protected]', name: 'Recipient 2' }
  ],
  subject: 'Hello',
  text: 'This is a test email'
})

🌐 HTML Email

await postie.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Hello',
  html: '<h1>Hello</h1><p>This is an HTML email.</p>'
})

📎 With Attachments

await postie.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Hello',
  text: 'This is a test email',
  attachments: [
    {
      filename: 'document.pdf',
      path: '/path/to/document.pdf'
    }
  ]
})

🎯 Special Methods

notify()

Sends a notification email with a "[NOTIFICATION]" prefix.

await postie.notify({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'System Update',
  text: 'The system has been updated'
})

alert()

Sends an alert email with an "[ALERT]" prefix.

await postie.alert({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'High CPU Usage',
  text: 'CPU usage is above 90%'
})

ping()

Sends a simple ping email.

await postie.ping({
  from: '[email protected]',
  to: '[email protected]'
})

📋 Template Support

Template Engine Setup

Postie supports any template engine that follows the standard template engine interface. Here are examples for different template engines:

Handlebars

const Handlebars = require('handlebars')
const handlebarsEngine = {
  compile: Handlebars.compile,
  render: (compiled, data) => compiled(data)
}
postie.setTemplateEngine(handlebarsEngine)

EJS

const ejs = require('ejs')
const ejsEngine = {
  compile: (template) => ejs.compile(template),
  render: (compiled, data) => compiled(data)
}
postie.setTemplateEngine(ejsEngine)

Custom Template Engine

You can create your own simple template engine:

const customEngine = {
  render: (template, data) => {
    return template.replace(/\{\{(\w+)\}\}/g, (match, key) => data[key] || match)
  }
}
postie.setTemplateEngine(customEngine)

Send Template Email

You can send template emails in two ways:

  1. Using a template string:
await postie.sendTemplate({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Welcome',
  template: 'Hello {{name}}, Welcome to {{company}}!',
  data: {
    name: 'John Doe',
    company: 'Our Company'
  }
})
  1. Using a template file:
await postie.sendTemplate({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Welcome',
  template: path.join(__dirname, 'templates/welcome.hbs'),
  data: {
    name: 'John Doe',
    company: 'Our Company',
    role: 'Developer'
  }
})

Template Engine Interface

To use a custom template engine, implement the following interface:

const customEngine = {
  // Required: Function to render the template with data
  render: (template, data) => {
    // Return the rendered template string
    return renderedTemplate
  },
  
  // Optional: Function to compile the template
  compile: (template) => {
    // Return a compiled template function
    return compiledTemplate
  }
}

🔌 Middleware

Add middleware functions to modify email options before sending.

// Add logging middleware
postie.use((emailOptions, next) => {
  console.log('Sending email:', emailOptions)
  next()
})

// Add custom header middleware
postie.use((emailOptions, next) => {
  emailOptions.headers = {
    ...emailOptions.headers,
    'X-Custom-Header': 'value'
  }
  next()
})

📧 Email Triggering By Aliases

Postie allows you to define reusable email configurations with aliases and trigger them with optional overrides. This is useful for setting up reusable email configurations.

Define an Alias

// Define a welcome email alias
postie.define('user-welcome', {
  from: '[email protected]',
  subject: 'Welcome to Our Platform',
  template: 'Hello {{name}}, welcome to {{company}}!',
  data: {
    company: 'Example Inc'
  }
})

// Define a notification alias
postie.define('system-update', {
  type: 'notify',
  from: '[email protected]',
  subject: 'System Update',
  text: 'A new system update is available'
})

// Define an alert alias
postie.define('high-usage', {
  type: 'alert',
  from: '[email protected]',
  subject: 'High Resource Usage',
  text: 'CPU usage is above 90%'
})

Trigger an Alias

// Trigger welcome email with overrides
await postie.trigger('user-welcome', {
  to: '[email protected]',
  data: {
    name: 'John Doe'
  }
})

// Trigger system update
await postie.trigger('system-update', {
  to: '[email protected]'
})

// Trigger alert with custom message
await postie.trigger('high-usage', {
  to: '[email protected]',
  text: 'Memory usage is above 95%'
})

Alias Configuration Options

You can use any of the following options in your alias configuration:

  • Basic email options (from, to, subject, text, html)
  • Template options (template, data)
  • Special types (type: 'notify', type: 'alert', type: 'ping')
  • Attachments
  • Headers
  • Any other options supported by the email sending methods

When triggering an alias, you can override any of these options by passing them in the overrides object.

💻 CLI Usage

Configure SMTP

postie configure \
  --host smtp.gmail.com \
  --port 587 \
  --user [email protected] \
  --pass your-app-password \
  --secure false

Send Email

# Basic email
postie send \
  --from [email protected] \
  --to [email protected] \
  --subject "Hello" \
  --text "This is a test email"

# Send with HTML
postie send \
  --from [email protected] \
  --to [email protected] \
  --subject "Hello" \
  --html template.html

# Send with attachments
postie send \
  --from [email protected] \
  --to [email protected] \
  --subject "Hello" \
  --text "This is a test email" \
  --attachments file1.pdf,file2.pdf

Using CLI Aliases

Postie supports predefined email configurations through CLI aliases in your .postierc file. These aliases use the event-based triggering system under the hood.

# Send a predefined notification
postie send --alias notify-admin

# Send a system alert
postie send --alias system-alert

When you use a CLI alias:

  1. Postie looks up the alias configuration in your .postierc file
  2. It uses the event-based triggering system to send the email
  3. The email is sent using the configured SMTP settings

You can override any alias configuration with command-line arguments:

# Override the recipient for a predefined notification
postie send --alias notify-admin --to "[email protected]"

# Override the subject for a system alert
postie send --alias system-alert --subject "Custom Alert"

📁 Configuration Files

Global Configuration (~/.postie/config.json)

{
  "devMode": false,
  "retryAttempts": 3,
  "retryDelay": 1000,
  "transporter": {
    "host": "smtp.gmail.com",
    "port": 587,
    "secure": false,
    "auth": {
      "user": "[email protected]",
      "pass": "your-app-password"
    }
  }
}

Project Configuration (.postierc)

You can create a .postierc file in your project root to specify default options for that project. This is useful when you have project-specific email settings. The settings in .postierc will override the global configuration from ~/.postie/config.json.

Example .postierc file:

{
  "emailDefaults": {
    // Basic email options
    "from": "[email protected]",
    "fromName": "Project Team",
    "subject": "Default Subject",
    "text": "Default email content",
    "html": "<h1>Default HTML content</h1>",

    // Recipients
    "to": "[email protected]",
    "toName": "Team Members",
    "cc": "[email protected]",
    "ccName": "Project Manager",
    "bcc": "[email protected]",
    "bccName": "Archive",

    // Multiple recipients (array format)
    "to": [
      "[email protected]",
      { "email": "[email protected]", "name": "Project Manager" }
    ],
    "cc": [
      "[email protected]",
      { "email": "[email protected]", "name": "Code Reviewer" }
    ],
    "bcc": [
      "[email protected]",
      { "email": "[email protected]", "name": "Audit Team" }
    ],

    // Attachments
    "attachments": [
      "docs/report.pdf",
      "docs/status.xlsx"
    ]
  },

  // SMTP settings (overrides global config)
  "smtp": {
    "host": "smtp.project.com",
    "port": 587,
    "secure": false,
    "auth": {
      "user": "[email protected]",
      "pass": "project-password"
    },
    "debug": true,
    "logger": true
  },

  // Postie configuration (overrides global config)
  "configure": {
    "devMode": false,
    "retryAttempts": 3,
    "retryDelay": 1000
  },

  // CLI Aliases
  "aliases": {
    "notify-admin": {
      "to": "[email protected]",
      "subject": "Alert!",
      "text": "Something happened"
    },
    "welcome-user": {
      "type": "notify",
      "to": "{{email}}",
      "subject": "Welcome {{name}}!",
      "template": "Hello {{name}}, welcome to our platform!",
      "data": {
        "company": "Example Inc"
      }
    },
    "system-alert": {
      "type": "alert",
      "to": "[email protected]",
      "subject": "System Alert",
      "text": "{{message}}"
    }
  }
}

🚨 Error Handling

Postie provides comprehensive error handling for various scenarios:

Connection Errors

try {
  await postie.testConnection()
} catch (error) {
  console.error('SMTP connection failed:', error.message)
}

Email Sending Errors

try {
  await postie.send(emailOptions)
} catch (error) {
  console.error('Failed to send email:', error.message)
  // Error details include:
  // - SMTP response
  // - Connection status
  // - Retry attempts
}

Configuration Errors

try {
  postie.configure(invalidConfig)
} catch (error) {
  console.error('Invalid configuration:', error.message)
}

Retry Mechanism

Postie automatically retries failed email sends based on configuration:

  • Number of retry attempts
  • Delay between retries
  • Exponential backoff

🔧 Development Mode

Development mode provides additional features for testing and debugging:

Enable Development Mode

postie.configure({
  devMode: true
})

Features in Development Mode

  1. Email Preview: Emails are not actually sent
  2. Debug Logging: Detailed logs of email processing
  3. Template Testing: Easy testing of email templates
  4. Configuration Validation: Strict validation of settings

Using Development Mode

// Configure for development
postie.configure({
  devMode: true,
  retryAttempts: 1,    // Fewer retries in development
  retryDelay: 100      // Shorter delay in development
})

// Send test email
await postie.send({
  to: '[email protected]',
  subject: 'Test Email',
  text: 'This is a test email'
})
// Email will be logged but not sent