{"_id":"@bunmail/smtp","name":"@bunmail/smtp","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@bunmail/smtp","version":"0.0.1","description":"Direct-to-MX SMTP client for Bun. First-class TLS observability + cert-validation reporting + DKIM signing. Zero npm dependencies.","keywords":["smtp","bun","mail","email","dkim","starttls","mx","deliverability"],"homepage":"https://github.com/mohamedboukari/bunmail-smtp#readme","bugs":{"url":"https://github.com/mohamedboukari/bunmail-smtp/issues"},"repository":{"type":"git","url":"git+https://github.com/mohamedboukari/bunmail-smtp.git"},"license":"MIT","author":{"name":"mohamedboukari"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"engines":{"bun":">=1.3.0"},"scripts":{"build":"bun build src/index.ts --outdir dist --target bun --format esm && bunx tsc --emitDeclarationOnly --outDir dist","typecheck":"bunx tsc --noEmit","test":"bun test","lint":"bunx tsc --noEmit","prepublishOnly":"bun run build && bun test"},"devDependencies":{"@types/bun":"latest","typescript":"^5.6.0"},"publishConfig":{"access":"public"},"_id":"@bunmail/smtp@0.0.1","gitHead":"1c729fdc9f734131a7b1783c5cec8c80175b47cb","_nodeVersion":"24.3.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-nWAf2BTkjE6DyE/RkMfzveh+wlnKfM3RKMOG9qGVhSqXTN0vpIZbT4NXQa0SC7edFqE33hutZVZXuJWnM57zcQ==","shasum":"ef3beaf028f603c1d34aa18242eb8b696db7febe","tarball":"https://registry.npmjs.org/@bunmail/smtp/-/smtp-0.0.1.tgz","fileCount":7,"unpackedSize":25330,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDSOD1iPbcl9VEG0ux3ZR4UQ+acgRNnxSqAqkmUJ4b6EAiA9QuPKQmzRFjyWRhHAffKAV/0RRvoQGbJ464wD5XWLsQ=="}]},"_npmUser":{"name":"mohamedboukari","email":"mouhamedboukari20@gmail.com"},"directories":{},"maintainers":[{"name":"mohamedboukari","email":"mouhamedboukari20@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/smtp_0.0.1_1778444209066_0.191579008587752"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-10T20:16:48.908Z","0.0.1":"2026-05-10T20:16:49.210Z","modified":"2026-05-10T20:16:49.540Z"},"maintainers":[{"name":"mohamedboukari","email":"mouhamedboukari20@gmail.com"}],"description":"Direct-to-MX SMTP client for Bun. First-class TLS observability + cert-validation reporting + DKIM signing. Zero npm dependencies.","homepage":"https://github.com/mohamedboukari/bunmail-smtp#readme","keywords":["smtp","bun","mail","email","dkim","starttls","mx","deliverability"],"repository":{"type":"git","url":"git+https://github.com/mohamedboukari/bunmail-smtp.git"},"author":{"name":"mohamedboukari"},"bugs":{"url":"https://github.com/mohamedboukari/bunmail-smtp/issues"},"license":"MIT","readme":"# @bunmail/smtp\n\n> Direct-to-MX SMTP client for [Bun](https://bun.sh). First-class TLS observability + cert validation reporting + DKIM signing. Zero npm dependencies.\n\n[![npm](https://img.shields.io/npm/v/@bunmail/smtp.svg)](https://www.npmjs.com/package/@bunmail/smtp)\n[![license](https://img.shields.io/npm/l/@bunmail/smtp.svg)](LICENSE)\n\n---\n\n> [!WARNING]\n> **v0.0.1 is a scaffolding release.** The full API surface is declared so you can write code against it today, but `sendMail()` throws `NotImplementedError` at runtime. The SMTP state machine + DKIM signing + TLS observability land in **v0.1.0**. Don't ship code that calls `sendMail()` until then. Watch the repo for the v0.1.0 release notes.\n\n## Why\n\nMost Bun email projects today reach for `nodemailer`. It works, but in direct-MX mode (no relay, send straight to the recipient's MX server) it has three sharp edges:\n\n1. **TLS state is opaque.** You don't know which cipher was negotiated, whether the peer cert validated, or even whether STARTTLS was used at all — the `info` response doesn't surface any of it. The only path to that data is parsing the SMTP transcript out of the `logger` option, which is fragile.\n2. **Cert validation is all-or-nothing.** `rejectUnauthorized: false` is the standard MTA-to-MTA practice (self-signed and expired certs are everywhere), but there's no way to track *what would have happened* under strict mode, and no way to enforce strict validation for known-good MX hosts (Gmail, Outlook).\n3. **DKIM signing is a separate plugin.** Works fine, but means another dep to keep current.\n\n`@bunmail/smtp` is opinionated about all three:\n\n- Every `sendMail` returns `result.tls.{used, protocol, cipher, peerCert.{subject, issuer, validFrom, validTo, selfSigned, validated}}` — captured natively, no log scraping.\n- Opportunistic TLS is the default (matching real-world MTA practice). `requireValidFor: [\"gmail.com\"]` opts into strict cert validation for receivers where you know it should work.\n- DKIM signing is built-in (RFC 6376), implemented against `node:crypto`. No plugin, no extra dep.\n\n## Install\n\n```bash\nbun add @bunmail/smtp\n```\n\n## Usage *(v0.1.0 surface)*\n\n```ts\nimport { sendMail } from \"@bunmail/smtp\";\n\nconst result = await sendMail({\n  from: \"hello@your-domain.com\",\n  to: \"user@gmail.com\",\n  subject: \"Welcome\",\n  html: \"<p>Hi!</p>\",\n  text: \"Hi!\",\n\n  dkim: {\n    domain: \"your-domain.com\",\n    selector: \"bunmail\",\n    privateKey: process.env.DKIM_KEY_PEM!,\n  },\n\n  tls: {\n    requireValidFor: [\"gmail.com\"], // strict cert validation for known-good MX\n  },\n});\n\nconsole.log(\"Delivered via\", result.mxHost);\nconsole.log(\"TLS used:\", result.tls.used);\nconsole.log(\"Cipher:\", result.tls.cipher);\nconsole.log(\"Cert validated:\", result.tls.peerCert?.validated);\n```\n\n### Result shape\n\n```ts\n{\n  messageId: string;\n  accepted: string[];\n  rejected: string[];\n  mxHost: string;\n  tls: {\n    used: boolean;\n    protocol?: \"TLSv1.2\" | \"TLSv1.3\" | string;\n    cipher?: string;\n    peerCert?: {\n      subject: string;\n      issuer: string;\n      validFrom: Date;\n      validTo: Date;\n      selfSigned: boolean;\n      validated: boolean;\n    };\n  };\n  trace?: string[]; // SMTP transcript when debug: true\n}\n```\n\n## Design constraints\n\n- **Bun-only.** Uses `Bun.connect()`, `node:tls`, `node:dns/promises`, `node:crypto`. Does not target Node.\n- **Zero npm dependencies.** Pure stdlib. No transitive supply-chain surface beyond Bun itself.\n- **Direct-to-MX only (v0.1).** No relay / no auth / no pooled transport. Send-to-the-recipient's-MX is the only path supported.\n- **Strict TypeScript.** No `any`, `exactOptionalPropertyTypes: true`, `noUncheckedIndexedAccess: true`.\n\nIf you need pooled transports, auth/relay mode, or Node compatibility — `nodemailer` is the right answer.\n\n## Roadmap\n\n- **v0.0.1** *(this release)* — scaffolding. Type surface only. Throws.\n- **v0.1.0** — SMTP state machine (EHLO → STARTTLS → MAIL FROM → RCPT TO → DATA → QUIT), DKIM signing, TLS metadata capture, opportunistic + strict modes. Tested against a fake-server harness.\n- **v0.2.0** — auth/relay mode (PLAIN/LOGIN), connection pooling.\n- **v1.0.0** — once the surface stabilises and BunMail has run on it in production for a quarter.\n\n## Used by\n\n- [**BunMail**](https://github.com/mohamedboukari/bunmail) — self-hosted email API. Reference implementation; the package is extracted from BunMail's outbound transport.\n\n## License\n\n[MIT](LICENSE) © mohamedboukari\n","readmeFilename":"README.md","_rev":"1-cda848fe57df5bd28690c11144648f56"}