DEV Community

Jelmer Migchelbrink
Jelmer Migchelbrink

Posted on

How We Generate 600M+ Cold Email Variations From One Template (Open Source)

Last month our cold emails started landing in spam.

The culprit? Sending nearly identical emails to hundreds of prospects. Gmail and Outlook spotted the pattern and tanked our deliverability.

The fix: unique variations for every single email. Not just swapping names - actually different sentences, different phrasing, different structure.

We needed millions of variations. Here's how we built it.

The Problem with Basic Spintax
Most spintax parsers handle simple patterns like:

{Hello|Hi|Hey} {there|friend}

This gives you 6 variations. Fine for small campaigns.

But what if you need this?

{Hello|Hi {there|{dear|lovely} friend}}

That's nested spintax - and most libraries choke on it.

Our Solution: Recursive Parsing
We built a parser that handles unlimited nesting depth:

import { spin, generate, analyze } from '@coldagency/spintax';

const template = `
{Hi|Hey|Hello} {{firstName}},

{I noticed|I saw} {{companyName}} {on LinkedIn|while researching {the {SaaS|B2B|tech} space|companies in {{industry}}}}.

{We help|At Cold Agency, we help} {B2B companies|founders} {book {15-30|20-40} {meetings|demos}|fill their pipeline} {per month|monthly}.

{Quick question|Curious} - {are you currently|is {{companyName}}} {doing any {outbound|cold outreach}|{investing in|focused on} outbound}?

{Cheers|Best},
{Jelmer|Your name}
`;

const stats = analyze(template);
console.log(stats.totalCombinations);
// → 609,638,400 unique variations

609 million variations from one template. Each one reads naturally.

How It Works
The math is simple multiplication:

{Hi|Hey|Hello} → 3 options
{on LinkedIn|...} → 5 options (nested!)
{book...|fill...} → 10 options
...

3 × 5 × 10 × ... = 609,638,400

The tricky part is parsing nested braces correctly. Here's the core algorithm:

function parseSpintax(text) {
const segments = [];
let currentIndex = 0;

while (currentIndex < text.length) {
const openBrace = text.indexOf('{', currentIndex);

if (openBrace === -1) {
segments.push([text.slice(currentIndex)]);
break;
}

// Track brace depth for nested syntax
let depth = 1;
let closeBrace = openBrace + 1;
while (depth > 0) {
if (text[closeBrace] === '{') depth++;
if (text[closeBrace] === '}') depth--;
closeBrace++;
}

// Recursively process nested options
const options = splitOptions(text.slice(openBrace + 1, closeBrace - 1));
segments.push(options);
currentIndex = closeBrace;
}

return segments;
}

The key insight: track brace depth to find the matching closing brace, then recursively process each option.

Three Generation Modes
// Random variations (default) - for campaigns
generate(template, { count: 50 });

// All combinations - for A/B testing
generate(template, { mode: 'all' });

// Sequential - for previewing
generate(template, { mode: 'sequential', count: 10 });

Real-World Usage
We use this for:

Cold email campaigns - Each recipient gets a unique email
A/B testing - Generate all headline variations
Content at scale - Product descriptions, meta tags, etc.
// A/B test headlines
const headlines = generate(
'{Boost|Increase|Skyrocket} your {sales|revenue} by {50%|2x|10x}',
{ mode: 'all' }
);
// → 27 unique headlines to test

Get It
npm install @coldagency/spintax

GitHub: github.com/coldagency-io/spintax

Zero dependencies. TypeScript ready. MIT licensed.

We're ColdAgency - we help B2B companies book meetings through cold outreach. This library is a small part of our stack that we thought others might find useful.

We contribute 1% of our revenue to carbon removal via Stripe Climate.

Bonus: Grab our free LinkedIn Carousel templates on Figma.

Want to chat? Book a free call.

Questions? Drop a comment below.

Top comments (0)