Quick Start Guide

Get started with Mailcraft in 5 minutes.

Installation

npm install @mailcraft/sdk @mailcraft/adapter-resend
# or
pnpm add @mailcraft/sdk @mailcraft/adapter-resend
# or
yarn add @mailcraft/sdk @mailcraft/adapter-resend

1. Define Your Brand

Create a brand.json file:

{
  "name": "Acme",
  "sender": {
    "fromEmail": "noreply@acme.com",
    "fromName": "Acme Team"
  },
  "business": {
    "legalName": "Acme Inc."
  }
}

Or in code:

import { Mailcraft, type BrandProfile } from "@mailcraft/sdk";

const brand: BrandProfile = {
  name: "Acme",
  sender: {
    fromEmail: "noreply@acme.com",
    fromName: "Acme Team"
  },
  business: {
    legalName: "Acme Inc."
  }
};

const mailcraft = new Mailcraft(brand);

2. Render an Email

const rendered = mailcraft.render("welcome", {
  to: ["user@example.com"],
  title: "Welcome to Acme!",
  body: "Thanks for signing up. Let's get started."
});

console.log(rendered.html);  // Full HTML email
console.log(rendered.text);  // Plain text version

3. Send an Email

Using Resend

import { ResendAdapter } from "@mailcraft/adapter-resend";

// Get API key from environment
const adapter = new ResendAdapter(process.env.RESEND_API_KEY);

// Send the email
const result = await mailcraft.send(
  "welcome",
  {
    to: ["user@example.com"],
    title: "Welcome to Acme!",
    body: "Thanks for signing up."
  },
  adapter
);

console.log(`Sent! Message ID: ${result.metadata?.messageId}`);

Using AWS SES

import { SesAdapter } from "@mailcraft/adapter-ses";

const adapter = new SesAdapter("us-east-1");

const result = await mailcraft.send(
  "welcome",
  {
    to: ["user@example.com"],
    title: "Welcome to Acme!",
    body: "Thanks for signing up."
  },
  adapter
);

console.log(`Sent! Message ID: ${result.id}`);

4. Handle Errors

import {
  MailcraftValidationError,
  MailcraftRenderError,
  MailcraftSendError
} from "@mailcraft/sdk";

try {
  await mailcraft.send("welcome", input, adapter);
} catch (error) {
  if (error instanceof MailcraftValidationError) {
    console.error("Invalid input:", error.message);
  } else if (error instanceof MailcraftRenderError) {
    console.error("Rendering failed:", error.message);
  } else if (error instanceof MailcraftSendError) {
    console.error(
      `${error.provider} error: ${error.payload.reason}`
    );
  }
}

5. Test Templates with CLI

Install the CLI:

npm install @mailcraft/cli

Test rendering:

mailcraft test welcome \
  --brand brand.json \
  --input title="Welcome!" \
  --input body="Thanks for joining"

Test and send:

mailcraft test welcome \
  --brand brand.json \
  --recipient user@example.com \
  --send \
  --input title="Welcome!"

Common Email Types

Verification Code

await mailcraft.send(
  "verification",
  {
    to: ["user@example.com"],
    code: "123456",
    link: "https://app.com/verify?token=xyz"
  },
  adapter
);

Receipt/Invoice

await mailcraft.send(
  "receipt",
  {
    to: ["customer@example.com"],
    receiptId: "RCP-2024-001",
    currency: "USD",
    total: "99.99",
    items: [
      { name: "Premium Plan", quantity: 1, amount: "99.99" }
    ]
  },
  adapter
);

Announcement

await mailcraft.send(
  "announcement",
  {
    to: ["users@example.com"],
    title: "New Feature: Dark Mode",
    body: "We've launched dark mode...",
    cta: {
      label: "Try It",
      url: "https://app.com/settings/theme"
    }
  },
  adapter
);

Newsletter/Digest

await mailcraft.send(
  "digest",
  {
    to: ["subscriber@example.com"],
    title: "Weekly Digest",
    entries: [
      {
        title: "Article 1",
        body: "Summary...",
        url: "https://blog.com/1"
      },
      {
        title: "Article 2",
        body: "Summary...",
        url: "https://blog.com/2"
      }
    ]
  },
  adapter
);

Full Example

import { Mailcraft, type BrandProfile } from "@mailcraft/sdk";
import { ResendAdapter } from "@mailcraft/adapter-resend";

// 1. Define brand
const brand: BrandProfile = {
  name: "Acme",
  visual: {
    primaryColor: "#ff5733"
  },
  sender: {
    fromEmail: "noreply@acme.com",
    fromName: "Acme"
  },
  business: {
    legalName: "Acme Inc."
  }
};

// 2. Create Mailcraft instance
const mailcraft = new Mailcraft(brand);

// 3. Create adapter
const adapter = new ResendAdapter(process.env.RESEND_API_KEY);

// 4. Send email
async function main() {
  try {
    const result = await mailcraft.send(
      "welcome",
      {
        to: ["user@example.com"],
        title: "Welcome to Acme!",
        body: "We're excited to have you."
      },
      adapter
    );

    console.log(`✓ Email sent: ${result.id}`);
  } catch (error) {
    console.error("✗ Failed:", error);
  }
}

main();

Next Steps

  1. Explore archetypes - Check out each template type in API Reference
  2. Learn best practices - See Best Practices Guide for production patterns
  3. Use the CLI - Send batch emails with the CLI
  4. Customize brand - Add colors, logo, voice to BrandProfile
  5. Add custom adapters - Build adapters for other providers

Common Issues

"Cannot find module @mailcraft/adapter-resend"

Install it:

npm install @mailcraft/adapter-resend

"MailcraftValidationError: to is required"

Make sure to is an array with email addresses:

// ❌ Wrong
await mailcraft.send("welcome", { title: "Hi" }, adapter);

// ✅ Correct
await mailcraft.send("welcome", {
  to: ["user@example.com"],
  title: "Hi"
}, adapter);

"MailcraftSendError: 401 Unauthorized"

Check your API key is correct:

# Resend
echo $RESEND_API_KEY  # Should start with 're_'

# AWS SES
aws sts get-caller-identity  # Should succeed

Email not received

  1. Verify from address is your verified sender domain
  2. Add unsubscribe link in brand footer
  3. Check spam folder
  4. Verify sender reputation with provider

See Email Deliverability for more.

Support