<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Steve Lebleu</title>
    <description>The latest articles on Forem by Steve Lebleu (@steve-lebleu).</description>
    <link>https://forem.com/steve-lebleu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F433352%2Fa0975aef-cebc-431b-b7b7-092c615d2d94.jpg</url>
      <title>Forem: Steve Lebleu</title>
      <link>https://forem.com/steve-lebleu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/steve-lebleu"/>
    <language>en</language>
    <item>
      <title>Agnostic email sending in Node.js</title>
      <dc:creator>Steve Lebleu</dc:creator>
      <pubDate>Sat, 25 Apr 2026 08:33:30 +0000</pubDate>
      <link>https://forem.com/steve-lebleu/agnostic-email-sending-in-nodejs-3klf</link>
      <guid>https://forem.com/steve-lebleu/agnostic-email-sending-in-nodejs-3klf</guid>
      <description>&lt;p&gt;The &lt;a href="https://github.com/steve-lebleu/cliam" rel="noopener noreferrer"&gt;Cliam package&lt;/a&gt; is back on track with a serious update about the quality, the dX, the flexibility and the security.&lt;/p&gt;

&lt;p&gt;For those ones that are not aware of what Cliam can achieve for them (and believe me, he can), just a short trailer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One input. One output. Any provider. Now more than ever.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And some number that matters&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10 providers. 1 interface. 0 new runtime dependencies in v3.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pick your provider. Switch tomorrow. Your code doesn't care.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Cliam&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cliam&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Cliam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user.welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// always the same&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The last marketing post is &lt;a href="https://dev.to/steve-lebleu/email-sending-in-nodejs-7ka"&gt;here&lt;/a&gt;. Let's quickly deep dive into the v3 release logs.&lt;/p&gt;
&lt;h2&gt;
  
  
  New providers
&lt;/h2&gt;

&lt;p&gt;Two heavy hitters join the roster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resend&lt;/strong&gt; - the developer-first email API built for the modern stack. Clean, predictable, fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon SES&lt;/strong&gt; - enterprise-grade deliverability at AWS scale. And because we know you hate unnecessary dependencies: SES authentication (AWS Signature V4) is implemented natively using Node.js built-in &lt;code&gt;crypto&lt;/code&gt;. No &lt;code&gt;@aws-sdk&lt;/code&gt;. No bloat. Zero new runtime dependencies.&lt;/p&gt;


&lt;h2&gt;
  
  
  Stack upgraded
&lt;/h2&gt;

&lt;p&gt;Cliam now runs on &lt;strong&gt;TypeScript 6&lt;/strong&gt;. ESM all the way, &lt;code&gt;moduleResolution: Bundler&lt;/code&gt;, built with tsup. No CommonJS cruft, no compatibility shims.&lt;/p&gt;

&lt;p&gt;The toolchain got a pass too: Biome 2.x handles linting and formatting, Bun runs the test suite, and &lt;code&gt;tsc --noEmit&lt;/code&gt; is wired in as a dedicated &lt;code&gt;typecheck&lt;/code&gt; script so your IDE and your CI agree on what's broken.&lt;/p&gt;


&lt;h2&gt;
  
  
  DX improved
&lt;/h2&gt;

&lt;p&gt;The API surface got cleaner.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;inlineImages&lt;/code&gt; is gone. It was never doing what you thought it was. Use &lt;code&gt;content&lt;/code&gt; attachments like everyone else.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sendinblue&lt;/code&gt; is also gone. It was Brevo. It's still Brevo. Update your config: &lt;code&gt;provider: 'brevo'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Template IDs now live exclusively on the transporter configuration, not scattered across options. One place, one source of truth.&lt;/li&gt;
&lt;li&gt;Theme colors are now injected as named Handlebars variables (&lt;code&gt;primaryColor&lt;/code&gt;, &lt;code&gt;secondaryColor&lt;/code&gt;, …) instead of post-render hex string replacement. Predictable. Debuggable. Actually makes sense.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Security improved
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;56 vulnerabilities. Including criticals. Now 0.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The previous architecture routed all providers - including HTTP API ones - through nodemailer, dragging along its entire dependency tree. That tree was old, wide, and full of known CVEs.&lt;/p&gt;

&lt;p&gt;v3 cuts it at the root. HTTP API providers (Brevo, Mailersend, Mailgun, Mailjet, Mandrill, Postmark, Resend, Sendgrid, SES, Sparkpost) now talk to their APIs through our own thin &lt;code&gt;HttpClient&lt;/code&gt; wrapper built on &lt;code&gt;ky&lt;/code&gt;. Nodemailer stays for SMTP - but only for SMTP, pinned to its latest maintained release (v8), with a clean bill of health.&lt;/p&gt;

&lt;p&gt;Less surface. Less trust. Less exposure.&lt;/p&gt;

&lt;p&gt;The rest of the security picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS SES requests are signed per-request using a proper Signature V4 implementation: timestamp, payload hash, HMAC chain, the works. No pre-shared static tokens flying around.&lt;/li&gt;
&lt;li&gt;All provider API key formats are validated at configuration time with provider-specific Joi regexes. You know immediately if something is wrong, not when your first email fails at 2am.&lt;/li&gt;
&lt;li&gt;Sandbox mode remains a hard gate: nothing leaves the process when it's on.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Type system cleaned up
&lt;/h2&gt;

&lt;p&gt;The internal type system went through a full consistency pass.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enums replaced with &lt;code&gt;as const&lt;/code&gt; objects + derived union types - one source of truth, no parallel declarations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IMail.meta&lt;/code&gt; is now narrowed: &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;replyTo&lt;/code&gt; are required by the type, not just by convention.&lt;/li&gt;
&lt;li&gt;Body interfaces defined per provider, ready to be wired into &lt;code&gt;build()&lt;/code&gt; return types for full end-to-end type coverage.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Bundle size improved
&lt;/h2&gt;

&lt;p&gt;Before v3, &lt;code&gt;import { Cliam } from 'cliam'&lt;/code&gt; silently loaded every provider, all ten of them, their HTTP clients, their payload mappers, all of it. You used Brevo. You got Sparkpost too. And Mailjet. And the rest.&lt;/p&gt;

&lt;p&gt;Now providers are tree-shakeable. Import everything at once, or load only what you actually ship:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Cliam&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cliam/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cliam/providers/brevo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// that's it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Your bundler sees exactly what you use. Nothing more makes it into your artifact.&lt;/p&gt;


&lt;h2&gt;
  
  
  Types improved
&lt;/h2&gt;

&lt;p&gt;The public API is now fully typed and fully exported. Consumers get first-class access to every interface they need:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IPayload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IClientConfiguration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IAddressable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IAttachment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cliam&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No more reaching into internals. No more &lt;code&gt;any&lt;/code&gt; patches at the call site. Your IDE knows what &lt;code&gt;meta.from&lt;/code&gt; is. Your compiler catches the typo before you do.&lt;/p&gt;


&lt;h2&gt;
  
  
  Configuration improved
&lt;/h2&gt;

&lt;p&gt;Two modes, your choice, no process assassination.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Programmatic — config lives in your code&lt;/span&gt;
&lt;span class="nx"&gt;Cliam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;transporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// File-based — config lives in .cliamrc.js&lt;/span&gt;
&lt;span class="nx"&gt;Cliam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configureFromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/path/to/config.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The critical part: bad configuration used to call &lt;code&gt;process.exit()&lt;/code&gt;. Your app just died, silently, in the middle of startup, with a log line you may or may not have seen. That's gone. Configuration errors now throw, which means you catch them, you log them your way, you decide what happens next. Your process is yours again.&lt;/p&gt;



&lt;p&gt;Thanks for the reading, enjoy your dev, and see you there:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.npmjs.com/package/cliam" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;npmjs.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/steve-lebleu" rel="noopener noreferrer"&gt;
        steve-lebleu
      &lt;/a&gt; / &lt;a href="https://github.com/steve-lebleu/cliam" rel="noopener noreferrer"&gt;
        cliam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Agnostic transactional email sending in Node.js environment
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b9451ff5b5f46b808d86bad019121126709d5ee8d92bd1ad2fd790de53169c67/68747470733a2f2f63646e2e6b6f6e6665722e62652f696d616765732f636c69616d2f6173736574732f62616e6e65722d636c69616d2e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/b9451ff5b5f46b808d86bad019121126709d5ee8d92bd1ad2fd790de53169c67/68747470733a2f2f63646e2e6b6f6e6665722e62652f696d616765732f636c69616d2f6173736574732f62616e6e65722d636c69616d2e706e67" alt="Cliam"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nodejs.org/docs/latest-v18.x/api/index.html" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7b526fd8320b08610a0b4f2b6d13e8e89e1d81cbaa87c9a315ba534748fe08c0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6f64652d31382e31392e302d696e666f726d6174696f6e616c3f6c6f676f3d6e6f64652e6a7326636f6c6f723d343338353344" alt="Node"&gt;&lt;/a&gt;
&lt;a href="https://bun.sh/docs/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/02a6114272ce39fbfe2be23de26eebaca45b382e03a8c258fe65a283f5f849cd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f42756e2d312e332e31312d696e666f726d6174696f6e616c3f6c6f676f3d62756e26636f6c6f723d666637336138" alt="Bun"&gt;&lt;/a&gt;
&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f540ab93b4a0f664b34522547153a9ad4668b3174f267deeb4483d1c70a25c5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547970657363726970742d362e302e332d696e666f726d6174696f6e616c3f6c6f676f3d7479706573637269707426636f6c6f723d324637344330" alt="TypeScript"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/steve-lebleu/cliam/actions/workflows/build.yml/badge.svg?branch=main"&gt;&lt;img src="https://github.com/steve-lebleu/cliam/actions/workflows/build.yml/badge.svg?branch=main" alt="Github action workflow status"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/f471c00c7729ec3445d89b0178655187367e0cf75fd4cf692b253706d21d68be/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f73746576652d6c65626c65752f636c69616d3f6c6f676f3d476974687562"&gt;&lt;img src="https://camo.githubusercontent.com/f471c00c7729ec3445d89b0178655187367e0cf75fd4cf692b253706d21d68be/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f73746576652d6c65626c65752f636c69616d3f6c6f676f3d476974687562" alt="GitHub Release"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/gpl-license.php" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c7a95ac714f5c4a10a8de7bb8b79afceeb75fec0cc0ee605e6d60bd23abb9982/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f73746576652d6c65626c65752f636c69616d3f6c6f676f3d676974687562" alt="GPL Licence"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://qlty.sh/gh/steve-lebleu/projects/cliam" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b3867d94ba1826f5f0555cdeba5e6d7386d3e60dec665f980c68601cda8866f8/68747470733a2f2f716c74792e73682f67682f73746576652d6c65626c65752f70726f6a656374732f636c69616d2f6d61696e7461696e6162696c6974792e737667" alt="Maintainability"&gt;&lt;/a&gt;
&lt;a href="https://qlty.sh/gh/steve-lebleu/projects/cliam" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d57a97aac6e3602a2c9281b487b3d677f2cd1e0c6ebd35c9d7ed7a09052a47da/68747470733a2f2f716c74792e73682f67682f73746576652d6c65626c65752f70726f6a656374732f636c69616d2f636f7665726167652e737667" alt="Code Coverage"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Transactional emails with a kick&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Agnostic transactional email sending in Node.js environment&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&amp;gt; Why ?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;To improve and facilitate the implementation, the flexibility and the maintenance of transactional emailing tasks.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&amp;gt; Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Agnostic transactional email sending using web API or SMTP server. One &lt;a href="https://github.com/steve-lebleu/cliam/wiki/Email-payload" rel="noopener noreferrer"&gt;input&lt;/a&gt;, one &lt;a href="https://github.com/steve-lebleu/cliam/wiki/Email-response" rel="noopener noreferrer"&gt;output&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Multiple simultaneous transporters.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/steve-lebleu/cliam/wiki/Configuration-with-cliamrc.js" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt; based, not implementation based: easy switch between different modes.&lt;/li&gt;
&lt;li&gt;Normalized &lt;a href="https://github.com/steve-lebleu/cliam/wiki/Transactions" rel="noopener noreferrer"&gt;transactions events&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Securized payloads.&lt;/li&gt;
&lt;li&gt;Customisable default templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&amp;gt; Table of contents&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#requirements" rel="noopener noreferrer"&gt;Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#selective-imports" rel="noopener noreferrer"&gt;Selective imports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#beneficiary-use-cases" rel="noopener noreferrer"&gt;Beneficiary use cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#supported-web-api-providers" rel="noopener noreferrer"&gt;Supported web API providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#upgrading-to-v3" rel="noopener noreferrer"&gt;Upgrading to v3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#licence" rel="noopener noreferrer"&gt;Licence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam/wiki" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 id="user-content-requirements" class="heading-element"&gt;&amp;gt; Requirements&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Node.js &amp;gt;= 18.19.0&lt;/li&gt;
&lt;li&gt;NPM &amp;gt;= 10.2.3&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 id="user-content-getting-started" class="heading-element"&gt;&amp;gt; Getting started&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Install&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; npm i cliam --save&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Configure&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Cliam must be configured once at application startup, before any call to &lt;code&gt;mail()&lt;/code&gt;. Two approaches are available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A - Pass a configuration object directly:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight highlight-source-ts notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-v"&gt;Cliam&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'cliam'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-k"&gt;type&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-v"&gt;IClientConfiguration&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'cliam'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/steve-lebleu/cliam" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>node</category>
      <category>mailing</category>
      <category>typescript</category>
    </item>
    <item>
      <title>VoidZero is driving the unification of the JS ecosystem</title>
      <dc:creator>Steve Lebleu</dc:creator>
      <pubDate>Sat, 21 Mar 2026 13:24:38 +0000</pubDate>
      <link>https://forem.com/steve-lebleu/voidzero-is-driving-the-unification-of-the-javascript-ecosystem-3k1h</link>
      <guid>https://forem.com/steve-lebleu/voidzero-is-driving-the-unification-of-the-javascript-ecosystem-3k1h</guid>
      <description>&lt;p&gt;&lt;a href="https://voidzero.dev/" rel="noopener noreferrer"&gt;VoidZero&lt;/a&gt; launch week is drawing to a close, and the world of Javascript development has just been given a significant boost. If you follow developments in build tools, you’ll know that fragmentation is rife, and that it’s difficult to stay at the cutting edge without using the best tool for each task. With the latest announcements regarding &lt;a href="https://vite.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;, &lt;a href="https://oxc.rs/" rel="noopener noreferrer"&gt;Oxlint&lt;/a&gt; and &lt;a href="https://vitest.dev/" rel="noopener noreferrer"&gt;Vitest&lt;/a&gt;, Evan You team is taking a major step towards the goal of unifying everything to improve performance and simplicity.&lt;/p&gt;

&lt;p&gt;Here are the key takeaways from this wave of updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oxlint: no more trade-offs between speed and compatibility
&lt;/h2&gt;

&lt;p&gt;Until now, choosing Oxlint meant sacrificing the ESLint plugin ecosystem in favour of Rust’s performance.&lt;/p&gt;

&lt;p&gt;That is no longer the case: Oxlint has reached a major milestone with its JS Plugins Alpha.&lt;/p&gt;

&lt;p&gt;In fact, your ESLint plugins now run in Oxlint without any modifications, with execution speeds up to 100 times faster than with ESLint. And as the folks at Void are so helpful, they’ve provided a migration tool (&lt;code&gt;@oxlint/migrate&lt;/code&gt;) that allows for an automatic transition from your existing configuration.&lt;/p&gt;

&lt;p&gt;Suffice to say that following the arrival of &lt;a href="https://biomejs.dev/" rel="noopener noreferrer"&gt;Biome.js&lt;/a&gt;, competition is becoming very, very fierce for ESLint, which has historically always suffered from limitations in execution, configuration and compatibility. It’s a drop-in replacement for around 80% of users, already adopted by major projects such as Preact and PostHog.&lt;/p&gt;

&lt;h2&gt;
  
  
  One bundler to rule them all with Vite 8 and Rolldown
&lt;/h2&gt;

&lt;p&gt;This is undoubtedly the most significant architectural change. Vite 8 is moving away from the esbuild (dev) / Rollup (prod) combination in favour of Rolldown, its new bundler, which is also written in Rust.&lt;/p&gt;

&lt;p&gt;In practical terms, what does this mean?&lt;/p&gt;

&lt;p&gt;Firstly, a clear unification between your local build and your production build. No more surprises or inconsistencies between your environments.&lt;/p&gt;

&lt;p&gt;Secondly, well – thanks to Rust – builds are 10 to 30 times faster than with Rollup. For example, the teams at Linear reportedly saw their build times drop from 46 seconds to 6 seconds, which is quite significant.&lt;/p&gt;

&lt;p&gt;Finally, the bundler now natively supports tsconfig paths and decorators, and offers a new, much more flexible codeSplitting API. A breath of fresh spring air, as they say.&lt;/p&gt;

&lt;h2&gt;
  
  
  More stability and less “flaky tests” at Vitest side
&lt;/h2&gt;

&lt;p&gt;Vitest 4.1 keeps pace with native support for Vite 8 and features designed for large-scale projects.&lt;/p&gt;

&lt;p&gt;Anyone who has written tests for an asynchronous application knows the drill: they leak, they hang left, right and centre, and they’re often difficult to debug. Vitest now offers asynchronous leak detection to put an end once and for all to the timers that clutter up workflows.&lt;/p&gt;

&lt;p&gt;In addition, you can now assign tags to your test suites to organise them more effectively. It’s not the most groundbreaking update, but it can be useful for large codebases.&lt;/p&gt;

&lt;p&gt;Finally, VoidZero is already anticipating new development workflows by equipping Vitest with a “reporter agent”, an output optimised for AI coding agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Towards a “Zero Config” experience
&lt;/h2&gt;

&lt;p&gt;The project goes beyond individual tools. The aim is to cover the entire application lifecycle to provide a complete value chain.&lt;/p&gt;

&lt;p&gt;Vite+ (Alpha) centralises everything via a single binary called vp. It acts as a task orchestrator with a persistent cache. No need to configure ESLint, Prettier or Vitest separately! A single vite.config.ts file drives the entire toolchain.&lt;/p&gt;

&lt;p&gt;This makes setup very simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vp create&lt;/code&gt; generates a new project&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vp dev&lt;/code&gt; starts the development server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vp check&lt;/code&gt; performs linting, formatting and type checking in a single line&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vp test&lt;/code&gt; runs tests using Vitest,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vp build&lt;/code&gt; creates an optimised production build,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vp run&lt;/code&gt; orchestrates monorepo tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Void, the deployment platform announced by Evan You, brings things full circle by offering an Infrastructure-as-Code approach, where the Void SDK analyses your code to automatically provision the necessary resources (DB, Auth, AI inference). And it doesn’t stop there, as the platform offers native support for the MCP protocol: developers can now not only write your code, but also autonomously set up and deploy the infrastructure on Void.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;p&gt;The Javascript ecosystem is emerging from a (long) period of having a “scattered toolkit” to now natively integrate linting, testing, building and deployment under a single technological umbrella (Rust + Vite).&lt;/p&gt;

&lt;p&gt;VoidZero offers a super-smooth developer experience, where performance comes as standard.&lt;/p&gt;

&lt;p&gt;They are not the only ones heading in this direction – Biome springs to mind – but they provide a more comprehensive solution that will significantly improve business workflows and influence the ecosystem.&lt;/p&gt;

&lt;p&gt;To find out more, you can consult the official migration guides on the &lt;a href="https://voidzero.dev/blog" rel="noopener noreferrer"&gt;VoidZero blog&lt;/a&gt; or explore the &lt;a href="https://vite.dev/" rel="noopener noreferrer"&gt;Vite 8&lt;/a&gt; documentation.&lt;/p&gt;




&lt;p&gt;This article has been translated from french original publication &lt;a href="https://lab.konfer.be/veille/voidzero-pousse-lunification-de-lecosysteme-js.html" rel="noopener noreferrer"&gt;VoidZero pousse l'unification de l'écosystème Javascript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>bundler</category>
      <category>webdev</category>
      <category>vite</category>
    </item>
    <item>
      <title>Email sending in Node.js</title>
      <dc:creator>Steve Lebleu</dc:creator>
      <pubDate>Thu, 22 Feb 2024 16:34:25 +0000</pubDate>
      <link>https://forem.com/steve-lebleu/email-sending-in-nodejs-7ka</link>
      <guid>https://forem.com/steve-lebleu/email-sending-in-nodejs-7ka</guid>
      <description>&lt;p&gt;As a developer, email sending is a recurent task across the projects.&lt;/p&gt;

&lt;p&gt;Most part of time, you have to deal with open source libraries, to switch from a library to another accross the projects, with some particular implementations and / or behaviors.&lt;/p&gt;

&lt;p&gt;As well, you can have a different need inside a same project just regarding the use case.&lt;/p&gt;

&lt;p&gt;For example, you can still need to send an email to a developer when a particular event is fired, or send a transactionnal email to say welcome to a new user. &lt;/p&gt;

&lt;p&gt;In the first case, a simple SMTP server can do the job internally.&lt;/p&gt;

&lt;p&gt;In the second case, it's more efficient to rely to a web API, able to manage statistics, bouncing, DKIM, templating, ...&lt;/p&gt;

&lt;p&gt;As well, you can need to deal with different providers at the same time. During a migration, for example. &lt;/p&gt;

&lt;p&gt;Some months ago, I was wondering how to provide something flexible and consistent to deal with this kind of repetitive issue.&lt;/p&gt;

&lt;p&gt;And I did it myself, because it was quite fun. 😎&lt;/p&gt;

&lt;p&gt;All the cases described above - and some others - are covered by a light NPM package.&lt;/p&gt;

&lt;p&gt;The main features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration based&lt;/li&gt;
&lt;li&gt;Agnostic appoach: same input, same output for all configurations&lt;/li&gt;
&lt;li&gt;Formalized transactions conventions&lt;/li&gt;
&lt;li&gt;Unlimited number of transporters inside the same project&lt;/li&gt;
&lt;li&gt;Support of different sending modes (SMTP and web API)&lt;/li&gt;
&lt;li&gt;Embeded view engine, stream or web API templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is Cliam, an agnostic and very flexible tool to deal with transactional email sending.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/steve-lebleu" rel="noopener noreferrer"&gt;
        steve-lebleu
      &lt;/a&gt; / &lt;a href="https://github.com/steve-lebleu/cliam" rel="noopener noreferrer"&gt;
        cliam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Agnostic transactional email sending in Node.js environment
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a5c7f7ea852d863f06ac72f00eab81188ab739315a7eb36ac880db18b7307ec7/68747470733a2f2f63646e2e6b6f6e6665722e62652f696d616765732f636c69616d2f6173736574732f62616e6e65722d636c69616d2e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/a5c7f7ea852d863f06ac72f00eab81188ab739315a7eb36ac880db18b7307ec7/68747470733a2f2f63646e2e6b6f6e6665722e62652f696d616765732f636c69616d2f6173736574732f62616e6e65722d636c69616d2e706e67" alt="Cliam"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/steve-lebleu/cliam/actions/workflows/build.yml/badge.svg?branch=main"&gt;&lt;img src="https://github.com/steve-lebleu/cliam/actions/workflows/build.yml/badge.svg?branch=main" alt="Github action workflow status"&gt;&lt;/a&gt;
&lt;a href="https://coveralls.io/github/steve-lebleu/cliam?branch=main" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2a9377b1b97cd4589ed029775db0a040538ce4716681f99287daacf18e356f9f/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f73746576652d6c65626c65752f636c69616d2f62616467652e7376673f6272616e63683d6d61696e" alt="Coverage Status"&gt;&lt;/a&gt;
&lt;a href="https://www.codefactor.io/repository/github/steve-lebleu/cliam" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b6e2c9c534d29a133e8ad5307d9f62cedf89df704094c81f0c9d900f9b70dfc5/68747470733a2f2f7777772e636f6465666163746f722e696f2f7265706f7369746f72792f6769746875622f73746576652d6c65626c65752f636c69616d2f6261646765" alt="CodeFactor"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/61c4f346300fe91790ee0c675bf8006ac96d4c8179ea67a57825d3e740d78f4d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f73746576652d6c65626c65752f636c69616d3f6c6f676f3d476974687562"&gt;&lt;img src="https://camo.githubusercontent.com/61c4f346300fe91790ee0c675bf8006ac96d4c8179ea67a57825d3e740d78f4d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f73746576652d6c65626c65752f636c69616d3f6c6f676f3d476974687562" alt="GitHub Release"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/gpl-license.php" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/43075ac8ea7c9db28c5b00746349c52e1a49099a9eca5d90a75396f022163f8b/68747470733a2f2f6261646765732e66726170736f66742e636f6d2f6f732f67706c2f67706c2e7376673f763d313033" alt="GPL Licence"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Transactional emails with a kick&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Agnostic transactional email sending in Node.js environment 💥 💪 💊&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&amp;gt; Why ?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;To improve and facilitate the implementation, flexibility and maintenance of transactional emailing tasks.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&amp;gt; Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Agnostic transactional email sending using web API or SMTP server. One &lt;a href="https://github.com/steve-lebleu/cliam/wiki/Email-payload" rel="noopener noreferrer"&gt;input&lt;/a&gt;, one &lt;a href="https://github.com/steve-lebleu/cliam/wiki/Email-response" rel="noopener noreferrer"&gt;output&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Multiple simultaneous transporters.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/steve-lebleu/cliam/wiki/Configuration-with-cliamrc.js" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt; based, not implementation based : easy switch between different modes.&lt;/li&gt;
&lt;li&gt;Normalized &lt;a href="https://github.com/steve-lebleu/cliam/wiki/Transactions" rel="noopener noreferrer"&gt;transactions events&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Securized payloads.&lt;/li&gt;
&lt;li&gt;Customisable default templates.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&amp;gt; Table of contents&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#requirements" rel="noopener noreferrer"&gt;Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#beneficiary-use-cases" rel="noopener noreferrer"&gt;Beneficiary use cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#supported-web-api-providers" rel="noopener noreferrer"&gt;Supported web API providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam#licence" rel="noopener noreferrer"&gt;Licence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steve-lebleu/cliam/wiki" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 id="user-content-requirements" class="heading-element"&gt;&amp;gt; Requirements&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Node.js &amp;gt;= 18.19.0&lt;/li&gt;
&lt;li&gt;NPM &amp;gt;= 10.2.3&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 id="user-content-getting-started" class="heading-element"&gt;&amp;gt; Getting started&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Install&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; npm i cliam --save&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Configure&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Create a &lt;em&gt;.cliamrc.js&lt;/em&gt; module on the root of your project.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt; touch .cliamrc.js&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Define a minimalist configuration in &lt;em&gt;.cliamrc.js&lt;/em&gt; newly created:&lt;/p&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-smi"&gt;module&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-c1"&gt;exports&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-s"&gt;"sandbox"&lt;/span&gt;: &lt;span class="pl-c1"&gt;true&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-s"&gt;"transporters"&lt;/span&gt;: &lt;span class="pl-kos"&gt;[&lt;/span&gt;
    &lt;span class="pl-kos"&gt;{&lt;/span&gt;
      &lt;span class="pl-s"&gt;"id"&lt;/span&gt;: &lt;span class="pl-s"&gt;"unique-transporter-key"&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
      &lt;span class="pl-s"&gt;"auth"&lt;/span&gt;: &lt;span class="pl-kos"&gt;{&lt;/span&gt;
        &lt;span class="pl-s"&gt;"username"&lt;/span&gt;: &lt;span class="pl-s1"&gt;process&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/steve-lebleu/cliam" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Currently, following web api providers are supported: Mailgun, Mailjet, Brevo, Sendinblue, Sendgrid, Mandrill, Sparkpost, Mailsender and Postmark. Amazon SES and a lot of others should be integrated soon, but I prefer take the focus on some new features and to push more robustness before to embedd too much transporters.&lt;/p&gt;

&lt;p&gt;Have a good dev, enjoy and feel free to use and to share 🚀&lt;/p&gt;

</description>
      <category>email</category>
      <category>node</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
