Owning Your Email Orchestration Layer
Most businesses that run email sequences end up in one of two camps: they either hire an agency to build them in Mailchimp or Klaviyo and sign up for the "$500/month email SaaS tax", or they hire a developer to build a bespoke automation and then realize three months later that changing a single email copy requires a code deploy. Velocity X takes a third path. Instead of outsourcing remarketing sequences to Mailchimp, it ships with a React Flow-powered visual flow editor built directly into the dashboard. You design the flow — audience segment → wait 2 days → send email → branch on click → send again or pause — and the engine stores it as a JSONB graph in Supabase, executes it daily, and sends via Resend. No third-party subscription. No agency middleman. No code redeploy. This piece explains the architecture, why bundling beats the Mailchimp dependency, and how to think about email orchestration as part of your core product, not as a bolted-on feature.
The Mailchimp Model and Its Hidden Cost
If you've been living under a rock, here's the pitch: Mailchimp lets you drag-and-drop email sequences. You define a trigger (lead form signup), add a delay (wait 2 days), then send (email 1, 2, 3 in sequence). You can add conditions (if they clicked email 1, send email 2A; if they didn't, send 2B). On paper, it's ideal for non-technical teams.
The hidden cost is the subscription tax. Mailchimp charges per contact. At 2,000 contacts + audience segmentation + detailed send logs, you're paying $300-$600/month. Klaviyo is worse — $20-$100/month per user plus contact overage. For a small business running 4-6 parallel sequences, that's $400-$1,200/month on email alone. Annually, $5,000-$15,000. Over three years, a mid-market business pays $15,000-$45,000 just to send emails they could control themselves.
That's before you factor in the switching cost. Once your entire customer engagement flow lives in Mailchimp, moving to another platform (or building your own) requires exporting your sequence logic, redefining it in the new system, and re-wiring it into your CRM. The platform intentionally makes leaving painful.
Why Bundling a Flow Editor Into Your Dashboard Is Better
Velocity X's approach is: you already have a Supabase database, you already have a backend that talks to your CRM, you already have a dashboard. Building a visual flow editor on top of that is orders of magnitude cheaper than maintaining an ongoing Mailchimp subscription. The editor stores sequences as JSONB graphs. The engine is 200 lines of scheduler code that runs once per hour (via Supabase pg_cron or Netlify scheduled functions). Sends go through Resend. All the data lives in your database.
The financial outcome: $0/month in SaaS fees. The operational outcome: sequences you fully own and can modify without waiting for Mailchimp to push an update. The integration outcome: your flow editor can branch on any event in Velocity X (lead qualified, calendar meeting booked, payment processed) without custom webhooks or Zapier glue.
How the Visual Node Editor Works
Behold: a minimal sequence that looks simple but is actually five interlocking systems.
1. Node Types. The editor defines four node kinds: audience (filter contacts by CRM segment, email domain, or tag), wait (delay between 1 minute and 90 days), send_email (template selection + send), branch (on click, open, or no-action). Each node is a React component rendered in a <ReactFlow> canvas. Users drag them on, wire them together, add parameters (email template, wait duration, branch condition), save.
2. Flow Storage. The editor saves the entire flow as a single JSONB column in Supabase.
{
"id": "seq-remarketing-day2",
"name": "Post-signup Re-engagement",
"nodes": [
{
"id": "aud-1",
"type": "audience",
"data": { "segment": "inactive_7d" }
},
{
"id": "wait-1",
"type": "wait",
"data": { "hours": 48 }
},
{
"id": "send-1",
"type": "send_email",
"data": { "templateId": "email-re-engage-day2" }
},
{
"id": "branch-1",
"type": "branch",
"data": { "on": "click", "branches": ["clicked", "did_not_click"] }
},
{
"id": "send-2",
"type": "send_email",
"data": { "templateId": "email-re-engage-day4-clicked" }
}
],
"edges": [
{ "source": "aud-1", "target": "wait-1" },
{ "source": "wait-1", "target": "send-1" },
{ "source": "send-1", "target": "branch-1" },
{ "source": "branch-1", "target": "send-2", "condition": "clicked" }
]
}
3. Flow Execution. A scheduled worker (running once per hour) walks every active flow. For each flow, it queries the audience (contacts matching the segment), calculates who's ready for the next step based on wait timers and event history, and executes the next action (send or branch). Contact state is persisted in a flow_instances table that tracks which step each contact is on and when they entered it.
4. Event Integration. The magic piece: when a contact clicks an email, their click is recorded. The scheduler sees it and advances them down the "clicked" branch. When a lead is marked qualified in the CRM, the edge function fires, the flow engine checks if any active sequences are waiting on that event, and advances those contacts too. Sequences can branch on any Velocity X event, not just email events. That's where it beats Mailchimp.
5. Send via Resend. When a send_email node is reached, the flow engine calls resend.emails.send() with the template, contact email, and context. Response is logged to flow_instances. If Resend returns a delivery error, the contact is marked for retry on the next hour's run.
Why This Isn't Mailchimp Lite
The obvious question: "Isn't this just a worse version of Mailchimp?" Three reasons it's not.
First, deep CRM integration. Mailchimp can branch on email events. Velocity X can branch on any operational event in your Supabase schema: contact qualified, appointment booked, invoice paid, feedback form submitted, video watched. You wire one condition in the visual editor: "if contact is qualified, send them email-for-sales-ready". No webhooks, no Zapier, no code. The scheduler just checks the condition every run.
Second, AI subject lines. When a contact reaches a send_email node, the flow engine can fetch their engagement history (previous emails opened, click patterns, CRM notes) and pass it to Claude to generate a personalized subject line. Mailchimp does not do this. You get Mailchimp's canned subject suggestions. Velocity X generates your subject at send time, based on what the contact actually cares about.
Third, you own the data. Every send, every click, every contact journey lives in your Supabase database. You can query it directly, slice it by cohort, drill into why one sequence outperforms another without logging into a third-party platform. You can build custom dashboards (Recharts, Superset, Metabase) on top of your flow data. With Mailchimp, you're locked into their analytics UI.
The Architecture in Production
The scheduler runs as a Netlify scheduled function once per hour. Flow execution is state-managed in a flow_instances table that tracks each contact's position in each flow. The schema looks roughly like:
flow_instances:
id
flow_id (fk to flows table)
contact_id (fk to crm_contacts table)
current_node_id
entered_at (timestamp)
last_action_at (timestamp)
state (JSON: metadata per node type)
is_complete (boolean)
flows:
id
name
graph (JSONB: the full node + edge structure)
organization_id (RLS-gated)
is_active (boolean)
created_at
updated_at
The scheduler query is simple: "Give me all flow_instances where the current node is a wait node AND enough time has passed AND the instance is not complete." For each, advance to the next node and execute (send, branch calculation, etc.). If the next node is a branch, calculate the condition (check contact email engagement, CRM field, event log) and move the contact to the appropriate path. If it's a send, fire the email and update the instance state.
Resend integration is straightforward: the send node handler calls resend.emails.send() with the contact's email, template ID, and context. RLS policies ensure each organization can only execute and view flows + instances they own.
Common Concerns and FAQs
What if Resend goes down? Do my emails not send?
The scheduler records the send attempt to flow_instances with a status ("pending", "sent", "failed"). If Resend returns an error, the contact stays on that node and the scheduler retries on the next run. After 3 retries, the contact is marked "failed" and an alert fires. This pattern is more robust than Mailchimp because you see exactly what happened and can investigate directly in your database.
Can I A/B test sequences?
Yes. Clone a flow, change one node (send template 1 vs template 2), run both against similar cohorts, compare engagement metrics. You can also use the branch node to A/B test at send time: the condition could be "random()" to assign 50% of incoming contacts to path A and 50% to path B.
How do I handle unsubscribes?
When a contact unsubscribes (via Resend's List-Unsubscribe header or your own CRM unsubscribe flow), mark them with a flag in the crm_contacts table. The audience node can filter them out: "segment=inactive_7d AND unsubscribed!=true". Alternatively, add an audience-type node at the start of the flow that automatically stops processing if unsubscribed=true.
What about compliance (CAN-SPAM, GDPR, CASL)?
Resend handles CAN-SPAM footers. Your flow should include an audience node that respects consent (e.g., "marketing_consent=true"). The contact's journey is fully auditable in your database — you can produce a report of every email sent to every contact on request. This is actually easier to prove compliance on than Mailchimp because you own the logs.
Can multiple sequences run on the same contact?
Yes. The flow_instances table tracks each contact + each flow pairing independently. One contact can be in the "post-signup re-engagement" sequence and the "product-launch" sequence simultaneously. Branch logic can also enqueue new flows programmatically if needed (e.g., "if contact clicks, add them to sales-follow-up sequence").
How do I troubleshoot why a contact didn't receive an email?
Query flow_instances with contact_id and flow_id. You'll see the exact node they're on, when they entered it, whether they advanced, and the last_action_at timestamp. If the send attempted and failed, the status and error are logged. Compare that against the contact's crm_contacts state (are they unsubscribed? did they match the audience filter?) and the flow's current_node definition. You can answer "why" in 30 seconds, not 10 minutes of Mailchimp clicking.
The Bottom Line
Email remarketing sequences are not simple, and they're not optional for any business with a customer acquisition funnel. The question is whether you pay Mailchimp $10,000-$45,000 over three years, or you own the layer yourself. For teams with a Supabase backend and a dashboard already built, adding a visual flow editor costs 2-3 weeks of engineering once, then lives rent-free in your database forever. For service businesses, lead-gen plays, and SaaS sales funnels — basically any business where re-engagement is margin-positive — this is the leverage play. Velocity X ships with it built. Ask your next website builder why theirs doesn't.