Package Exports
- @oxog/mailer
Readme
@oxog/mailer
A zero-dependency email sending library for Node.js with SMTP protocol implementation from scratch.
Features
- Zero Dependencies: No external packages - everything implemented from scratch using only Node.js built-in modules
- TypeScript First: Complete TypeScript support with strict typing
- Modern API: Clean, intuitive API with Promise-based async/await support
- SMTP Compliance: Full SMTP protocol implementation (RFC 5321)
- Security: STARTTLS support, multiple authentication methods (PLAIN, LOGIN, CRAM-MD5, OAuth2)
- Plugin System: Extensible architecture with event-driven plugin support
- Connection Pooling: Efficient connection management for high-throughput applications
- Comprehensive Testing: 100% test coverage with robust error handling
Installation
npm install @oxog/mailerQuick Start
import { Mailer } from '@oxog/mailer';
const mailer = new Mailer({
host: 'smtp.gmail.com',
port: 587,
secure: false,
auth: {
user: 'your-email@gmail.com',
pass: 'your-app-password',
},
});
async function sendEmail() {
try {
const result = await mailer.send({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello from @oxog/mailer!',
text: 'This is a test email.',
html: '<h1>Hello!</h1><p>This is a test email.</p>',
});
console.log('Email sent:', result.messageId);
} catch (error) {
console.error('Error sending email:', error);
} finally {
await mailer.close();
}
}
sendEmail();Factory Methods for Popular Providers
// Gmail
const gmailMailer = Mailer.createGmailClient('user@gmail.com', 'app-password');
// Outlook/Hotmail
const outlookMailer = Mailer.createOutlookClient('user@outlook.com', 'password');
// Yahoo
const yahooMailer = Mailer.createYahooClient('user@yahoo.com', 'password');
// OAuth2 support
const gmailOAuth = Mailer.createGmailOAuth2Client('user@gmail.com', 'access-token');Configuration Options
interface MailerOptions {
host: string; // SMTP server hostname
port?: number; // SMTP server port (default: 587 for non-secure, 465 for secure)
secure?: boolean; // Use SSL/TLS connection (default: false)
auth?: {
type?: 'plain' | 'login' | 'cram-md5' | 'xoauth2';
user: string; // Username
pass?: string; // Password (not needed for OAuth2)
accessToken?: string; // OAuth2 access token
};
tls?: {
rejectUnauthorized?: boolean; // Verify server certificate (default: true)
minVersion?: string; // Minimum TLS version
ciphers?: string; // Allowed cipher suites
};
connectionTimeout?: number; // Connection timeout in ms (default: 10000)
greetingTimeout?: number; // Greeting timeout in ms (default: 5000)
socketTimeout?: number; // Socket timeout in ms (default: 60000)
pool?: boolean | PoolOptions; // Enable connection pooling
maxConnections?: number; // Max concurrent connections (default: 5)
maxMessages?: number; // Max messages per connection (default: 100)
rateLimit?: number; // Rate limit (messages per second, 0 = no limit)
logger?: boolean | Logger; // Enable logging
debug?: boolean; // Enable debug output
name?: string; // Client hostname (default: 'localhost')
}Message Format
interface Message {
from: string | Address; // Sender address
to: string | Address | Array<string | Address>; // Recipients
cc?: string | Address | Array<string | Address>; // CC recipients
bcc?: string | Address | Array<string | Address>; // BCC recipients
subject: string; // Email subject
text?: string; // Plain text body
html?: string; // HTML body
attachments?: Attachment[]; // File attachments
headers?: Record<string, string>; // Custom headers
priority?: 'high' | 'normal' | 'low'; // Message priority
references?: string; // Message references
inReplyTo?: string; // Reply-to message ID
messageId?: string; // Custom message ID
date?: Date; // Send date (default: now)
}
interface Address {
name?: string; // Display name
address: string; // Email address
}Error Handling
import { MailerError, ErrorCodes } from '@oxog/mailer';
try {
await mailer.send(message);
} catch (error) {
if (error instanceof MailerError) {
console.error('Mailer error:', error.code, error.message);
console.error('Solution:', error.solution);
console.error('Documentation:', error.documentation);
} else {
console.error('Unexpected error:', error);
}
}Plugin System
import { Plugin } from '@oxog/mailer';
const customPlugin: Plugin = {
name: 'custom-plugin',
version: '1.0.0',
install(mailer) {
mailer.on('beforeSend', (message) => {
console.log('About to send:', message.subject);
});
mailer.on('afterSend', (result) => {
console.log('Sent successfully:', result.messageId);
});
},
};
mailer.use(customPlugin);Development
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Build the package
npm run build
# Lint code
npm run lint
# Format code
npm run formatRequirements
- Node.js 14.0.0 or higher
- TypeScript 5.0+ (for development)
License
MIT
Contributing
Contributions are welcome! Please read the contributing guidelines and submit pull requests for any improvements.
Support
- GitHub Issues: Report bugs or request features
- Documentation: Full API documentation
- Examples: More examples
Comparison with Nodemailer
| Feature | @oxog/mailer | Nodemailer |
|---|---|---|
| Dependencies | 0 | 50+ |
| Bundle size | ~50KB | ~1MB+ |
| TypeScript | Native | Third-party types |
| Plugin system | Built-in | Limited |
| Connection pooling | Built-in | Built-in |
| OAuth2 | Built-in | Plugin required |
| Modern API | Promise-based | Callback + Promise |
Why Zero Dependencies?
- Security: No supply chain vulnerabilities from third-party packages
- Performance: Smaller bundle size and faster installation
- Reliability: No breaking changes from dependency updates
- Control: Full control over implementation and features
- Transparency: Easy to audit and understand the codebase