Skip to content

Marketing

Email Marketing — Resend Broadcasts vs Mailchimp vs ConvertKit

All articles
📬 🚀 📊

Mailchimp used to be the default. Mailchimp is now the warning sign. ConvertKit works if you're a creator. Resend Broadcasts is the dark horse that wins when you control the audience data.

Email is still the highest-ROI marketing channel. One problem: picking the right platform. Mailchimp was the easy answer for 15 years because it was free. Then they got acquired by Intuit, feature-gated the free tier into uselessness, and prices climbed. ConvertKit owns the creator newsletter market (Substack's main competitor, but better for monetisation). Resend Broadcasts launched in late 2024 and immediately changed the game for developers: React Email templates, Supabase audience sync, zero-dashboard design. If you're running a SaaS with customer data you already own, Resend is cheaper and more flexible than anything else. Here's the real breakdown, cost at scale, and when each platform actually wins.

What Even Is "Email Marketing" vs "Transactional Email"?

Quick distinction before we compare:

Transactional email is one-to-one: order confirmations, password resets, delivery notifications. Service-triggered, not a list. (Resend is built for this — read about it here.)

Broadcast email is one-to-many: newsletters, weekly digests, promotional campaigns, re-engagement drives. You own a list (or you import one), write once, send to everyone. Mailchimp, ConvertKit, and Resend Broadcasts all do this. But the workflows and pricing are wildly different.

The Three Platforms: Overview

Mailchimp: The legacy default. Free tier used to be generous (12k emails/month). Now it's crippled (500 contacts max). Paid tiers start at $13/month. Automation is buried in their dashboard — you'll spend hours building email workflows. They own the "free email marketing for startups" perception, so everyone thinks of Mailchimp first. That's its only advantage anymore.

ConvertKit: Built for creators (bloggers, podcasters, YouTubers). Starts at $29/month for up to 1,000 subscribers. Zero-based pricing: $0.30/subscriber above 1,000. Focus is automation, segmentation, and subscriber growth (they have affiliate signup flows built in). Dashboard is slick. You send through their UI, no code. It's Substack with better monetisation and creator tools.

Resend Broadcasts: (Launched late 2024.) Starts free: 3,000 emails/month. Then $50/month for 50k, $100 for 100k (flat-rate, not per-subscriber). The hook: you write emails in React (using Resend's React Email), sync audiences from Supabase, send from your app or a scheduled function. Full control, no dashboard theatre. Designed for developers who already have customer/subscriber data and want to blast it without vendor lock-in.

Pricing: The Honest Breakdown

Cost assumptions: 10k subscribers, 2 campaigns per month, 20% open rate (typical).

Mailchimp: $0–13/month for free → Standard tier. At 10k contacts, you're forced to paid: $13/mo (limited) or $20/mo (mid-tier automation). But wait — that's not all. Want detailed automation? $30/mo. Want custom templates and priority support? $199/mo. Real cost for a 10k-list small business: $30–50/month. At 100k subscribers, Mailchimp becomes $300+/month.

ConvertKit: 1–10k subscribers: $29–300/mo depending on subscriber count. For 10k subs, you're at the $199/month tier. For 50k, you're at $879/month. For 100k, $2,199/month. The math: $0.022/subscriber/month. ConvertKit's advantage is the creator tools (affiliate management, paid membership integration, embedded signup). That's why creators pay it. Ust marketing a SaaS product? You're overpaying for features you won't use.

Resend Broadcasts: 3k emails free/month. Then flat-rate monthly tiers. 10k subscribers × 2 campaigns = 20k emails = $50/month. 50k subscribers × 2 campaigns = 100k emails = $100/month. 100k subscribers = $200/month. The math: $0.001–2/email, not per-subscriber. If you send infrequently, you stay cheap. If your list grows but send frequency stays the same, cost doesn't explode.

Cost comparison, 10k subscriber list, 2 campaigns/month:

Provider      Monthly Cost   Per-Email Cost   Includes
Mailchimp     $30–50         ~$0.15–0.25     Dashboard, templates, basic automation
ConvertKit    $199           ~$0.001         Creator tools, affiliate management, no code
Resend        $50            ~$0.0025        React Email, Supabase sync, code-driven

Mailchimp gets expensive fast. ConvertKit is steady but assumes you're a creator (if you're not, skip it). Resend is the wildcard: cheap for SaaS, but only if you already own the audience data and are comfortable sending via code.

Feature Comparison: Automation, Segmentation, A/B Testing

Mailchimp: Automation exists but is clunky. Segment by open rate, click rate, subscriber tag, or static segments. Build workflows with if/then branches. A/B testing is limited (Mailchimp tests subject lines, not body copy effectively). Good: built-in integrations with Shopify, WooCommerce. Bad: feels like enterprise software from 2015.

ConvertKit: Automation is slick. Tag subscribers, trigger sequences on tag, segment by purchase history. A/B testing subject lines. Great for creators (tag fans by content type, send different emails to different cohorts). But: no direct Supabase integration, no code. You're clicking in their UI. Changes take time.

Resend Broadcasts: Automation is code. Write a cron function, fetch segmented audience from Supabase, send campaigns via React Email. A/B test by forking the campaign code, deploying variants to different branches, and measuring. No UI automation builder — everything is code (and version-controlled). This is fast for developers, slow for non-technical marketers.

Resend Broadcasts + Supabase: The Developer's Play

The Resend + Supabase combo is where it gets interesting for SaaS. You own subscriber data in Supabase. You build campaigns in code. You send on a schedule (or on-demand). Here's the pattern:

// supabase migrations: create subscribers table
create table subscribers (
  id uuid primary key default gen_random_uuid(),
  email text unique not null,
  created_at timestamp default now(),
  tags text[] default '{}', -- segment by tag
  unsubscribed boolean default false
);

-- indexes for speed
create index on subscribers(unsubscribed);
create index on subscribers using gin(tags);

// lib/emails/WeeklyDigest.tsx
import React from 'react';
import { Html, Body, Container, Heading, Text, Button, Section } from '@react-email/components';

export const WeeklyDigest = ({ userName, topPost, openCount }: any) => (
  <Html>
    <Body style={{ backgroundColor: '#f9fafb' }}>
      <Container style={{ backgroundColor: '#fff', padding: '40px', borderRadius: '8px' }}>
        <Heading>Your Weekly Digest, {userName}</Heading>
        <Text>This week, {openCount} of your posts hit trending.</Text>
        <Section style={{ marginTop: '20px', padding: '16px', backgroundColor: '#f3f4f6', borderRadius: '4px' }}>
          <Heading as="h3">{topPost.title}</Heading>
          <Text>{topPost.excerpt}</Text>
          <Button href={topPost.url} style={{ backgroundColor: '#6366f1', color: '#fff', padding: '10px 20px', borderRadius: '4px', textDecoration: 'none' }}>
            Read Full Post
          </Button>
        </Section>
        <Text style={{ marginTop: '20px', fontSize: '12px', color: '#666' }}>
          <a href="{unsubscribeUrl}">Unsubscribe</a>
        </Text>
      </Container>
    </Body>
  </Html>
);

// netlify/functions/send-weekly-digest.ts (cron-triggered)
import { Resend } from 'resend';
import { createClient } from '@supabase/supabase-js';
import { WeeklyDigest } from '../../lib/emails/WeeklyDigest';

const resend = new Resend(process.env.RESEND_API_KEY);
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY);

export default async (event: any) => {
  // Fetch all unsubscribed=false subscribers
  const { data: subscribers, error: fetchError } = await supabase
    .from('subscribers')
    .select('id, email, name, tags')
    .eq('unsubscribed', false);

  if (fetchError) {
    console.error('Supabase fetch failed:', fetchError.message);
    return { statusCode: 500, body: JSON.stringify({ error: fetchError.message }) };
  }

  const results = [];

  for (const sub of subscribers) {
    // Fetch their week's top posts from another table
    const { data: posts } = await supabase
      .from('posts')
      .select('title, excerpt, url')
      .eq('author_id', sub.id)
      .gte('created_at', new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString())
      .order('views', { ascending: false })
      .limit(1);

    const topPost = posts?.[0] || { title: 'No posts this week', excerpt: 'Check back next week!', url: 'https://yourapp.com' };

    try {
      const result = await resend.emails.send({
        from: 'Weekly Digest <digest@yourapp.com>',
        to: sub.email,
        subject: `Your Weekly Digest: ${topPost.title}`,
        react: WeeklyDigest({ userName: sub.name, topPost, openCount: posts?.length || 0 }),
        headers: {
          'List-Unsubscribe': `https://yourapp.com/unsubscribe?email=${encodeURIComponent(sub.email)}`
        }
      });

      results.push({ email: sub.email, success: !!result.data?.id });
    } catch (err: any) {
      console.error(`Failed to send to ${sub.email}:`, err.message);
      results.push({ email: sub.email, success: false, error: err.message });
    }
  }

  return {
    statusCode: 200,
    body: JSON.stringify({ sent: results.filter(r => r.success).length, failed: results.filter(r => !r.success).length, results })
  };
};

// netlify.toml
[[functions]]
path = "netlify/functions/send-weekly-digest.ts"

  [functions.config.schedule]
  cron = "0 9 * * 1" # Every Monday at 9 AM UTC

What you're seeing: cron-triggered weekly email. Audience lives in Supabase (you own it). Email is React (you version-control it). Sends per subscriber with personalization. Unsubscribe links work because you host the unsubscribe endpoint. Cost: $50/month for the Resend tier + your Netlify function (free). Compare that to $30 Mailchimp + $200 ConvertKit for the same reach. Resend wins.

When to Pick Each Platform

Pick Mailchimp if: You're a non-technical small business, already on Shopify, don't want to code, and accept higher costs. Honestly? Almost never. You're leaving money on the table.

Pick ConvertKit if: You're a creator (blogger, podcaster, YouTuber), want creator monetisation (paid memberships, affiliate management), and don't mind the per-subscriber cost. ConvertKit beats Substack here because it has better integrations and automation.

Pick Resend if: You're a developer, own subscriber data in Supabase (or any database), want to send campaigns from code, and care about cost at scale. You'll be 10x cheaper than Mailchimp and 5x cheaper than ConvertKit at 50k subscribers.

Six FAQs

Can I import my Mailchimp list to Resend?

Technically: export your list as CSV from Mailchimp, build a script to insert into Supabase, then send from Resend. Resend doesn't have a built-in import. But migrating is straightforward — it's the sync going forward that matters. Once in Supabase, you own it forever.

Does Resend track unsubscribes?

Resend doesn't manage opt-out lists — you do. Store `unsubscribed: true` in your Supabase subscribers table, and filter it out before sending (`where unsubscribed = false`). Add an unsubscribe endpoint in your app (`/api/unsubscribe?email=...`) that toggles the flag. Include the link in every email (CAN-SPAM requires it).

What about GDPR compliance?

All three platforms are GDPR-compliant (they have DPAs). But Resend puts compliance on you: you're responsible for storing consent, managing unsubscribes, and deleting data on request. Mailchimp and ConvertKit handle some of this in their UI. For SaaS, you probably have a privacy policy already — Resend just makes it explicit.

Can I A/B test email subject lines with Resend?

Resend doesn't have built-in A/B testing UI. You A/B test in code: write two campaign variants, split your audience by subscriber tag (tag 50% with "variant_a", 50% with "variant_b"), send both, and measure opens yourself (Resend logs them via webhooks). It's more work than Mailchimp, but you have full control.

What if I send from Resend but want Mailchimp analytics?

Don't. You'll duplicate data and confuse yourself. Pick one. If you need dashboards, Resend has basic ones — click rates, bounces, unsubscribes. Not fancy, but enough. If you need advanced analytics, you're over-thinking it. Track conversions in your app, not in email dashboards.

How do I handle list decay (people stop engaging)?

Tag subscribers by last engagement date. In Supabase: `update subscribers set tags = array_append(tags, 'inactive') where last_email_open < now() - interval '90 days'`. Then send a re-engagement campaign only to inactive tags. If they don't open that, remove them (delete or soft-delete with `unsubscribed = true`). This keeps your sender reputation clean.

The Bottom Line

Mailchimp is legacy bloat. You're paying for features you don't need, on a platform built for 2010-era email marketing. ConvertKit is the smart choice for creators — it's made for you, the automation is good, and the per-subscriber cost buys creator tools. Resend Broadcasts is the dark horse for developers: own your audience, send from code, version-control your emails, and save 80% on cost compared to Mailchimp. The Resend + Supabase pattern is how modern SaaS does email. Spin up a Supabase project, sync your customers, write campaigns in React, and send on schedule. If you're building a SaaS product and need a full marketing stack (email + landing pages + customer dashboards), Velocity X integrates this pattern out of the box. See how Aidxn builds SaaS products for the full story. For transactional email (order confirmations, password resets) flowing into broadcast data, read about Resend vs SendGrid vs Postmark.

Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.