C
CanxJS
v1.6.2
  • Learn
  • Blog
  • Showcase
C
CanxJS

Ultra-fast async MVC backend framework for Bun. Build production-ready APIs with elegance and speed.

Resources

  • Documentation
  • Learn
  • Blog
  • Showcase

Documentation

  • Introduction
  • Installation
  • Core Concepts
  • CLI Commands
  • API Reference

Legal

  • Privacy Policy
  • Terms of Service

© 2026 CanxJS. All rights reserved.

Built with ❤️ for Candra Kirana

  • Cluster Mode
  • Microservices
  • Observability
  • Security Layers
  • Universal Signals
  • Canx Flow
  • Maintenance
Enterprise

Canx Flow

Fault-tolerant workflow engine that survives server restarts and crashes. Build long-running business processes that never lose state.

State Persistence

Every step is persisted to the database. Resume from exactly where you left off.

Durable Timers

Sleep for days, weeks, or months. The server can restart without losing progress.

Automatic Retry

Failed steps are automatically retried with exponential backoff.

Fault Tolerant

Survives crashes, restarts, and deployments. Your workflows always complete.

Why Canx Flow?

Standard code fails if the server restarts in the middle of execution. Canx Flow persists the execution state to the database after every step. If the server crashes, it resumes automatically from the last successful step.

Defining a Workflow

Create workflows using the workflow() function. Each step is persisted and can be resumed if interrupted.

workflows/subscription.ts
1import { workflow } from 'canxjs';
2
3const subscriptionFlow = workflow('subscription', async (ctx, userId) => {
4
5 // Step 1: Charge
6 await ctx.step('charge', () => payment.charge(userId));
7
8 // Step 2: Sleep (Durable)
9 // Server can be offline during this time
10 await ctx.sleep('trial', 30 * 24 * 3600 * 1000); // 30 days
11
12 // Step 3: Renew
13 await ctx.step('renew', () => payment.renew(userId));
14
15});

Starting & Managing Workflows

Start workflows asynchronously and manage their lifecycle. Check status, cancel, or retry as needed.

app.ts
1// Start async (returns workflow ID)
2const id = await subscriptionFlow.start('user-123');
3
4// Check status
5const status = await subscriptionFlow.status(id);
6// { state: 'sleeping', step: 'trial', resumeAt: '2024-03-15T...' }
7
8// Cancel if needed
9await subscriptionFlow.cancel(id);

Step Types

MethodPurpose
ctx.step(name, fn)Execute once, cache result
ctx.sleep(name, ms)Durable timer that survives restarts
ctx.waitFor(name, event)Wait for external event
workflows/order.ts
1const orderFlow = workflow('order-processing', async (ctx, orderId) => {
2
3 // Regular step - executed once, result cached
4 const order = await ctx.step('fetch-order', () => {
5 return db.orders.find(orderId);
6 });
7
8 // Conditional step
9 if (order.requiresApproval) {
10 await ctx.step('wait-approval', () => {
11 return notifyManager(order);
12 });
13
14 // Durable sleep - survives restarts
15 await ctx.sleep('approval-timeout', 24 * 60 * 60 * 1000); // 24h
16 }
17
18 // Side effect step
19 await ctx.step('send-confirmation', () => {
20 return email.send(order.customerEmail, 'Order Confirmed');
21 });
22
23});

Next Steps

Explore other enterprise features to build scalable distributed systems.