Language SDK

Nodemailer works locally. Then production happens.

Nodemailer fails silently in production, leaks memory from unclosed connections, and doesn't work on serverless. Ark sends email over HTTPS—clear errors, no connection pools, works on Vercel, Lambda, and Workers.

26
MCP tools
Sub-second
Delivery
99.9%
Inbox rate
$0.50
Per 1K emails

Nodemailer is a debugging nightmare

Works perfectly in development. Deploy to production and emails silently don't send. No errors, no logs, just... nothing. Then you discover SMTP ports are blocked on your host, or your connection pool is leaking sockets, or Gmail decided to stop accepting your auth.

  • ×Silent failures in production—code works locally, nothing sends in prod
  • ×Memory leaks from createTransport() without close()—sockets stay open forever
  • ×Doesn't work on Vercel Edge, Cloudflare Workers, or any edge runtime (requires net, tls modules)
  • ×Gmail authentication randomly stops working after months with no code changes

HTTP API instead of SMTP

Ark sends email over HTTPS. No SMTP ports to open, no connection pools to manage, no silent failures. Works on every platform—Node.js, Vercel, Lambda, Workers, Deno.

Clear error responses—you know exactly what went wrong
No memory leaks—stateless HTTP requests, no connection pools
Works on serverless and edge (uses fetch, not net/tls modules)
Same behavior in development and production
2 minutes

Replace Nodemailer in 2 minutes

npm install, set one environment variable, send. No createTransport, no SMTP config, no close() to forget.

1

Install the SDK

Works with Node.js 18+, Bun, Deno. Full TypeScript types included.

npm install ark-email
2

Set your API key

One environment variable. No SMTP host, port, secure, auth object.

# .env
ARK_API_KEY=ark_live_xxxxxx
3

Send email

Three lines. Returns confirmation with message ID. Throws on error (no silent failures).

import { Ark } from "ark-email";

const ark = new Ark();  // Reads ARK_API_KEY from env

const { id } = await ark.emails.send({
  from: "[email protected]",
  to: "[email protected]",
  subject: "Welcome!",
  html: "<h1>You're in.</h1>",
});
console.log("Sent:", id);  // Confirmed delivery

Code examples

Copy and paste to get started quickly.

Express (no connection pool drama)
// routes/email.ts
import { Ark } from "ark-email";
import { Router } from "express";

// No createTransport(), no pool config, no close() to forget
const ark = new Ark();
const router = Router();

router.post("/signup", async (req, res) => {
  try {
    const { id } = await ark.emails.send({
      from: "[email protected]",
      to: req.body.email,
      subject: "Welcome to YourApp!",
      html: "<h1>You're in!</h1>",
    });
    res.json({ emailId: id });
  } catch (err) {
    // Actual error—not silent failure
    console.error("Email failed:", err.message);
    res.status(500).json({ error: "Email failed" });
  }
});

export default router;
Vercel Edge Function (actually works)
// app/api/welcome/route.ts
// Works on Vercel Edge—Nodemailer doesn't (requires net, tls modules)
import { Ark } from "ark-email";

export const runtime = "edge";  // Edge runtime—no Node.js modules

const ark = new Ark();

export async function POST(request: Request) {
  const { email, name } = await request.json();

  await ark.emails.send({
    from: "[email protected]",
    to: email,
    subject: `Welcome, ${name}!`,
    html: `<h1>Hi ${name}!</h1><p>Thanks for signing up.</p>`,
  });

  return Response.json({ sent: true });
}
Cloudflare Workers
// src/index.ts
// Nodemailer can't run here—no net/tls. Ark uses fetch.
import { Ark } from "ark-email";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const ark = new Ark({ apiKey: env.ARK_API_KEY });

    const { email } = await request.json();

    await ark.emails.send({
      from: "[email protected]",
      to: email,
      subject: "Your alert triggered",
      html: "<p>Something happened. Check it out.</p>",
    });

    return new Response(JSON.stringify({ sent: true }));
  },
};

What you can build

Production that actually sends

No more "works locally, silent in prod." Ark throws real errors and returns delivery confirmation. You'll know if email failed.

Serverless without workarounds

Vercel Edge, Lambda, Workers—all restrict SMTP ports or lack Node.js net/tls modules. Ark uses HTTPS on port 443. Works everywhere.

Long-running services without leaks

Nodemailer needs createTransport/close lifecycle. Miss a close() and sockets leak. Ark is stateless HTTP—nothing to close.

TypeScript-first development

Full type definitions. IDE autocomplete for every parameter. Catch bugs before runtime.

Why developers choose Ark

No silent failures

Ark throws on error and returns message ID on success. You always know what happened.

Works on edge and serverless

Uses fetch, not net/tls. Runs on Vercel Edge, Cloudflare Workers, Deno Deploy, and Lambda without SMTP port restrictions.

No memory leaks

Stateless HTTP requests. No connection pools to manage, no sockets to close, no createTransport() lifecycle.

Full TypeScript types

Built in TypeScript from day one. Every method, parameter, and response is typed. Your IDE knows everything.

What you get with Ark

Automatic SPF, DKIM, DMARC
Real-time webhooks
Suppression management
Unlimited domains
Unlimited team members
$2.50 (5,000 emails) welcome credit
No monthly fees

Frequently asked questions

Why not just use Nodemailer?

Nodemailer works until it doesn't. It fails silently in production (you think email sent but it didn't), leaks memory if you forget close(), and doesn't work on edge runtimes or serverless platforms that block SMTP. Ark uses HTTPS, so it works everywhere and fails loudly.

Does this work on Vercel Edge Functions?

Yes. Nodemailer requires Node.js net and tls modules that don't exist on edge runtimes. Ark uses fetch over HTTPS—it works on Vercel Edge, Cloudflare Workers, Deno Deploy, and any edge runtime.

What about AWS Lambda?

Lambda often blocks SMTP ports or has strict network policies. Ark uses HTTPS on port 443, which is always allowed. No VPC configuration, no NAT gateway setup.

Do I need to manage connections?

No. Nodemailer requires createTransport() and close() to manage SMTP connections. Forget close() and you leak sockets. Ark is stateless HTTP—each send() is independent, nothing to manage or clean up.

Is there CommonJS support?

Yes. The SDK supports both ES modules (import) and CommonJS (require). Works with any Node.js project.

What does it cost?

$0.50 per 1,000 emails. No monthly fees. $2.50 welcome credit (5,000 emails). Most apps run for months on the free credit.

npm install ark-email

No Nodemailer. No silent failures. No memory leaks. Works on serverless. 2 minutes to first email.