Segflow
Open Source & Self-Hosted

An open-source,full-code alternative to Customer.io

Segflow lets you write marketing automation flows in pure code. Instead of clicking through complex UIs, you can define user segments with SQL queries, write campaign logic in TypeScript, create email templates in React, and deploy everything with Git.

// Define your user properties
interface UserAttributes {
  email: string;
  name: string;
  lastLoginAt: string;
}

const config: SegflowConfig<UserAttributes> = {
  // Define user segments with SQL
  segments: {
    'inactive-users': {
      evaluator: (db) => db
        .select({ id: schema.users.id })
        .from(schema.users)
        .where(sql`${schema.users.attributes}->>'$.lastLoginAt' < NOW() - INTERVAL 30 DAY`)
    }
  },

  // Define campaign logic with TypeScript
  campaigns: {
    'winback-campaign': {
      segments: ['inactive-users'],
      behavior: 'dynamic',  // Auto-exits when user becomes active again
      flow: function* (ctx, rt) {
        for (let i = 0; i < 10; i++) {
          yield rt.sendEmail('winback');
          yield rt.wait({ days: 2 ** i }); // Wait 1, 2, then 4 days
        }
      }
    }
  }
};

Key Concepts

Segments = SQL Queries

Define user groups with the full power of SQL:

segments: {
  'big-spenders': {
    evaluator: (db) => db
      .select({ id: schema.users.id })
      .from(schema.users)
      .innerJoin(schema.events, eq(schema.events.userId, schema.users.id))
      .where(eq(schema.events.name, 'purchase'))
      .groupBy(schema.users.id)
      .having(sql`sum(${schema.events.attributes}->'$.amount') > 1000`)
  }
}

Campaigns = Generator Functions

Write complex flows with regular TypeScript:

campaigns: {
  'onboarding': {
    segments: ['new-users'],
    behavior: 'static',
    flow: function* (ctx, rt) {
      yield rt.sendEmail('welcome');
      yield rt.wait({ days: 1 });
      
      if (!ctx.user.profileCompleted) {
        yield rt.sendEmail('complete-profile-reminder');
      }
      
      yield rt.wait({ days: 3 });
      yield rt.sendEmail('feature-highlights');
    }
  }
}

Templates = React Components

Design emails with familiar tools:

templates: {
  'welcome': {
    subject: (user) => `Welcome ${user.name}!`,
    component: ({ user }) => (
      <Html>
        <Head />
        <Tailwind>
          <Body>
            <Preview className="text-blue-600">Welcome aboard!</Preview>
            <Text className="text-slate-600">Thanks for joining us {user.name}!</Text>
            <Button href="https://example.com/get-started">
              Get Started
            </Button>
          </Body>
        </Tailwind>
      </Html>
    )
  }
}

Frequently Asked Questions

How often do campaigns run?

Campaigns run in real-time. As soon as a user enters a segment, they start receiving the campaign. For `dynamic` campaigns, users exit immediately when they no longer match the segment criteria.

How do you prevent duplicate sends?

Segflow tracks each user's progress through campaigns in its database. Users can only be at one step in a campaign at a time.

What databases are supported?

Segflow uses MySQL to track its own state. Your application can use any database - you just need to send user events to Segflow via its API.

What email providers are supported?

Currently Postmark and Amazon SES. Adding new providers is straightforward through the open-source codebase.

Because the best marketing automation is the one you can actually program.

Segflow empowers developers to build sophisticated marketing automation workflows tailored to their unique business needs, all while maintaining full control over their code and data.

Get Started