npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dripengine/sdk

v0.1.5

Published

Official SDK for DripEngine — self-hostable email sequence engine.

Downloads

37

Readme

DripEngine

Open source, self-hostable email drip engine for developers.

Stop writing cron jobs. Define email sequences as YAML, enroll contacts with 3 lines of code, and let DripEngine handle the scheduling, conditions, retries, and delivery — on your own infrastructure.

import { DripEngine } from '@dripengine/sdk'

const drip = new DripEngine({ apiKey: process.env.DRIP_KEY })

await drip.enroll({
  sequenceId: 'onboarding',
  contact: { email: '[email protected]', plan: 'free' }
})

Why DripEngine?

Every SaaS needs drip emails. Most teams end up with the same mess — a cron job querying the database, an if/else chain checking conditions, a retry function that silently fails, and zero visibility into what actually sent.

DripEngine replaces all of that with a config file and an SDK call.

| | DIY approach | DripEngine | |---|---|---| | Setup time | Days | 2 minutes | | Time-based delays | Cron jobs | delay: 5d in YAML | | Condition branching | If/else spaghetti | Declarative conditions | | Retries | Hope | Exponential backoff | | Visibility | Grep logs | Dashboard | | Self-hostable | Yes (you built it) | Yes (one command) |


Features

  • Sequence-as-code — define entire email flows in YAML. Version control your sequences like any other config.
  • Condition branching — skip or cancel steps based on contact properties or events they've fired. No code required.
  • Smart cancellation — when a contact upgrades or completes an action, pending emails that are no longer relevant are automatically cancelled.
  • Any SMTP provider — works with Nodemailer, Resend, SendGrid, SES, Postmark, or any raw SMTP server.
  • Dashboard included — built-in Next.js dashboard for sequence health, contact timelines, and delivery logs.
  • Self-hostable — runs entirely on your infra with one docker-compose up. No vendor lock-in, no usage limits.
  • Cloud option — don't want to manage infra? Use our hosted version at dripengine.dev.

Quick start

Self-hosted (recommended)

Prerequisites: Docker Desktop

git clone https://github.com/nirvanjha2004/dripengine.git
cd dripengine
cp .env.example .env   # fill in your SMTP credentials
docker-compose up

That's it. Your API is running at http://localhost:8000 and your dashboard at http://localhost:3000.

Install the SDK

npm install @dripengine/sdk

Define a sequence

Create a YAML file in the sequences/ folder:

# sequences/onboarding.yaml
id: onboarding
trigger: user.signup

steps:
  - id: welcome
    delay: 0
    template: welcome-email

  - id: tip-day2
    delay: 1d
    template: first-tip
    condition:
      event_not_fired: user.completed_profile   # skip if they already did this

  - id: tip-day5
    delay: 5d
    template: second-tip
    condition:
      property: plan
      equals: free                              # skip if they upgraded

  - id: upgrade-nudge
    delay: 10d
    template: upgrade
    condition:
      property: plan
      equals: free

No restart needed — sequences are hot-reloaded.


Use the SDK

import { DripEngine } from '@dripengine/sdk'

const drip = new DripEngine({
  apiKey: process.env.DRIP_KEY,
  baseUrl: 'http://localhost:8000',   // or your deployed URL
})

// Enroll a contact when they sign up
await drip.enroll({
  sequenceId: 'onboarding',
  contact: {
    email: '[email protected]',
    name: 'John',
    timezone: 'Asia/Kolkata',
    properties: { plan: 'free' }
  }
})

// Fire an event when something happens in your app
// The engine will automatically cancel steps gated on this event
await drip.event({
  eventName: 'user.completed_profile',
  email: '[email protected]'
})

// Unenroll when they upgrade — stops all pending emails
await drip.unenroll({
  sequenceId: 'onboarding',
  email: '[email protected]'
})

Or use the REST API directly:

curl -X POST http://localhost:8000/enroll \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "sequence_id": "onboarding",
    "contact": {
      "email": "[email protected]",
      "properties": { "plan": "free" }
    }
  }'

Email templates

Templates live in the templates/ folder. Each template is a folder with three files:

templates/
  welcome-email/
    subject.txt    ← subject line (supports {{variables}})
    html.hbs       ← HTML body (Handlebars)
    text.hbs       ← plain text fallback

Example html.hbs:

<h1>Hey {{name}}</h1>
<p>Welcome! You're on the <strong>{{plan}}</strong> plan.</p>

Variables are automatically filled from the contact's properties.


Conditions

Conditions are evaluated at send time — not at schedule time. The engine always checks the contact's current state.

# Send only if a property matches
condition:
  property: plan
  equals: free

# Send only if a property does NOT match
condition:
  property: plan
  not_equals: paid

# Send only if an event has NOT been fired
condition:
  event_not_fired: user.completed_profile

# Send only if an event HAS been fired
condition:
  event_fired: user.invited_teammate

Email providers

Set PROVIDER in your .env:

# Nodemailer — any SMTP server (default)
PROVIDER=nodemailer
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASS=your-app-password

# Resend
PROVIDER=resend
RESEND_API_KEY=re_xxxx

# SendGrid
PROVIDER=sendgrid
SENDGRID_API_KEY=SG.xxxx

Dashboard

The built-in dashboard runs at http://localhost:3000:

  • Overview — total contacts, active enrollments, emails sent today
  • Sequences — per-sequence health with sent / skipped / failed breakdown
  • Contacts — search any email and see their full timeline
  • Logs — paginated delivery log with filtering by status and sequence

Architecture

┌─────────────────────────────────────────────────┐
│                 Ingestion layer                  │
│   REST API · SDK · Webhook triggers · CLI import │
└──────────────────────┬──────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────┐
│                  Core engine                     │
│  Scheduler · Condition evaluator · Retry manager │
│  Template renderer · Contact state (Postgres)    │
│              Queue: Redis + BullMQ               │
└──────────────────────┬──────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────┐
│               Delivery layer                     │
│     Nodemailer · Resend · SendGrid · SES         │
└─────────────────────────────────────────────────┘

Stack: FastAPI · Node.js · BullMQ · Redis · Postgres · Next.js · Docker


Self-hosting guide

Environment variables

| Variable | Required | Description | |---|---|---| | API_SECRET_KEY | Yes | Auth key for all API requests | | DATABASE_URL | Yes | Postgres connection string | | REDIS_HOST | Yes | Redis host | | PROVIDER | Yes | Email provider: nodemailer, resend, sendgrid | | SMTP_HOST | If nodemailer | SMTP server host | | SMTP_USER | If nodemailer | SMTP username | | SMTP_PASS | If nodemailer | SMTP password / app password | | RESEND_API_KEY | If resend | Resend API key | | SENDGRID_API_KEY | If sendgrid | SendGrid API key |

Scaling

The worker is stateless and horizontally scalable. To handle more volume, spin up more worker containers — BullMQ ensures no job is processed twice:

worker:
  deploy:
    replicas: 3

API reference

Full interactive docs available at http://localhost:8000/docs after starting the server.

| Method | Endpoint | Description | |---|---|---| | POST | /enroll | Enroll a contact into a sequence | | POST | /event | Fire an event for a contact | | POST | /unenroll | Remove a contact from a sequence | | GET | /dashboard/overview | Summary stats | | GET | /dashboard/sequences | Per-sequence health | | GET | /dashboard/contacts | Contact timeline | | GET | /dashboard/logs | Delivery log feed | | GET | /health | Health check |


Roadmap

  • [ ] Webhook ingestion (Stripe, GitHub, etc.)
  • [ ] A/B testing for email templates
  • [ ] Unsubscribe link handling
  • [ ] Multi-tenant support
  • [ ] Hosted cloud version

Contributing

PRs are welcome. Please open an issue first for anything beyond small fixes.

git clone https://github.com/nirvanjha2004/dripengine.git
cd dripengine
cp .env.example .env
docker-compose up

The API hot-reloads on save. The dashboard hot-reloads on save. The worker requires a restart on code changes.


License

MIT — use it, fork it, build on it.