Command-line tool to send an email, or automate repetitive emails.
Built with TypeScript and nodemailer. Engine-like design — can be embedded in VS Code extensions, GUIs, or any Node.js application.
# Install dependencies
npm install
# Build TypeScript
npm run build
# Send a quick text email
sendEmail -t someone@example.com "Hello from sendEmail"
# Show full help
sendEmail -hRun the setup script to create config/accounts/_default.js from the template:
bash .github/scripts/setup.sh.github\scripts\setup.batThen edit config/accounts/_default.js with your credentials.
For Gmail, use an App Password (requires 2FA).
Caution
config/accounts/ is excluded from git — it contains real credentials.
Never run git add -f config/accounts/ — this bypasses .gitignore and will expose your credentials.
See config/README.md for full details.
npm run build# Unix/macOS
chmod +x bin/sendEmail.sh
ln -s $(pwd)/bin/sendEmail.sh /usr/local/bin/sendEmail
# Windows: add the bin/ directory to your PATHsendEmail [options] [arguments]
| Mode | Example |
|---|---|
| Raw (quick text) | sendEmail -t user@example.com "Message" |
| Normal (structured) | sendEmail --send-to user@example.com --subject "Hello" --message-html body.html |
| Repetitive (bulk) | sendEmail --config-email newsletter --email-list subscribers --force |
# Quick text email
sendEmail -t someone@example.com "Quick message"
# HTML email
sendEmail --send-to john@example.com --subject "Report" --message-html ./report.html
# Markdown email (auto-converted to HTML)
sendEmail --send-to team@company.com --subject "Update" --message-file ./update.md
# Configured email template
sendEmail --config-email billing --send-to client@example.com
# Bulk send to list
sendEmail --config-email newsletter --email-list subscribers --force
# Show help
sendEmail -h
sendEmail -h options
sendEmail -h options:configurableRelative paths for --message-file, --message-html, and --message-text are resolved from your current working directory first; if no match is found, sendEmail falls back to its config/tool root.
sendEmail/
├── src/
│ ├── core/ # Core engine (interface-agnostic)
│ │ ├── engine.ts # EmailEngine class
│ │ ├── types.ts # All TypeScript interfaces
│ │ ├── config-loader.ts # Load configurations
│ │ ├── template-engine.ts # Template variable substitution
│ │ ├── list-processor.ts # Email list iteration
│ │ ├── attachment-loader.ts
│ │ └── validator.ts
│ ├── cli/ # CLI entry point
│ │ ├── index.ts # Main CLI runner
│ │ ├── parser.ts # Argument parsing
│ │ ├── help.ts # Help documentation
│ │ └── prompts.ts # Confirmation prompts
│ ├── utils/ # Utilities
│ │ ├── file-utils.ts
│ │ ├── logger.ts
│ │ ├── error-handler.ts
│ │ └── markdown-html.ts
│ └── tools/ # Tool scripts
│ ├── list-generator.ts # --new-list
│ ├── copy-tool.ts # --copy
│ └── test-runner.ts # --test
├── bin/
│ ├── sendEmail.js # Node.js entry (npm bin)
│ ├── sendEmail.sh # Unix/macOS wrapper
│ ├── sendEmail.cmd # Windows CMD wrapper
│ └── sendEmail.ps1 # PowerShell wrapper
├── config/
│ ├── _accounts/ # Template (versioned) — rename to accounts/ to activate
│ ├── accounts/ # !! git-ignored !! — your real credentials live here
│ │ ├── _default.js # REQUIRED default account
│ │ └── example.js
│ ├── emails/ # Configured email templates
│ │ ├── billing/
│ │ └── example/
│ └── globals/ # Reusable global templates
│ ├── footer/
│ └── example/
├── lists/ # Email lists (.json)
├── attachments/ # Email attachments
├── img/ # Embedded images
├── tests/
│ ├── unit/ # Unit tests (vitest)
│ ├── mock/server/ # Mock SMTP server
│ └── logs/ # Test logs
└── docs/
├── CLI-OPTIONS.md # Full options reference
├── CLI-CHEATSHEET.md # Quick reference
├── API.md # Engine API documentation
└── EXAMPLES.md # Real-world examples
// New-style (recommended):
export const account = {
service: 'gmail',
auth: { user: 'your@gmail.com', pass: 'app-password' },
};
// Or with custom SMTP:
export const account = {
host: 'smtp.example.com',
port: 587,
secure: false,
auth: { user: 'user@example.com', pass: 'password' },
};{
"from": "_default",
"subject": "Billing Statement - {{contact.name}}",
"html": "billingStatement",
"globals": ["footer"]
}{
"email-list": [
{ "email": "alice@example.com", "name": "Alice" },
{ "email": "bob@example.com", "name": "Bob" }
]
}Use in subject lines, HTML templates, and configurable text:
| Variable | Value |
|---|---|
{{contact.name}} |
Contact's name |
{{contact.email}} |
Contact's email |
{{contact.<field>}} |
Any custom field |
{{date}} |
2026-02-19 |
{{date.formatted}} |
February 19, 2026 |
{{list.index}} |
Current index (bulk send) |
{{list.count}} |
Total recipients |
Legacy placeholders (CH-EMAILONLIST, CHANGE_SEND_TO) are also supported.
import { EmailEngine, createEngineConfig } from './dist/core/engine.js';
const engine = new EmailEngine(createEngineConfig(process.cwd()));
await engine.initialize();
const result = await engine.sendEmail({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello',
html: '<p>Hello, World!</p>',
});See docs/API.md for full API documentation.
| Command | Description |
|---|---|
npm run build |
Compile TypeScript to dist/ |
npm run build:watch |
Watch mode compilation |
npm run dev |
Run CLI directly with tsx (no build needed) |
npm test |
Run tests in watch mode |
npm run test:run |
Run all tests once |
sendEmail --test |
Run tests via CLI |
- CLI-OPTIONS.md — Complete options reference
- CLI-CHEATSHEET.md — Quick reference
- API.md — Engine API for developers
- EXAMPLES.md — Real-world usage examples