Skip to content

Build with AI Assistants

Use your favorite AI coding assistant to build a complete Continuous History system — events, durable functions, projections, and time-travel debugging — guided by AI-generated code.

Prerequisites

  • Ironflow running locally (ironflow serve --dev)
  • An AI coding assistant (Claude Code, Cursor, Copilot, Windsurf, etc.)
  • Node.js 20+ and pnpm (or Go 1.25+ if following the Go track)

Step 1: Add the Agent Template

The agent template gives your AI assistant context about Ironflow’s SDK, patterns, and best practices. Copy it from the Agent Template page and save it in your project:

your-project/
├── agent.md # AI context file
├── src/
│ └── workflows/
└── package.json

Different AI tools read different files:

ToolRecommended File
Claude CodeCLAUDE.md or agent.md
Cursor.cursor/rules/*.mdc (preferred) or agent.md
GitHub Copilot.github/copilot-instructions.md or agent.md
Windsurf.windsurfrules or agent.md
Otheragent.md (most tools read markdown)

The MCP server (ironflow mcp) and shipped agent skills are deeper integration paths — see AI MCP Server and AI Skills.


Step 2: Start Ironflow

Terminal window
ironflow serve --dev

The --dev flag disables authentication so you can start building immediately. Server runs at http://localhost:9123.

Production Mode

When you’re ready for real workloads, drop the --dev flag. See Security for details.


Step 3: Ask the AI to Build a Recorded System

Use this prompt with your AI assistant. Notice it covers all four Continuous History pillars — emit, react, derive, and rewind:

Build an Ironflow system using TypeScript with @ironflow/node that:
1. REACT: Create a function triggered by "order.placed" events with recording
enabled. It should have three durable steps:
- "validate-order" — validates the order
- "process-payment" — charges the amount
- "send-confirmation" — sends email confirmation
2. DERIVE: Create a managed projection called "order-stats" that listens
to "order.placed" events and maintains a running total of orders
and revenue.
3. Wire both into a createWorker and start it.
Use pull mode (createWorker), not push mode (serve).
Enable recording: true on the function for time-travel debugging.

Expected AI Response

The AI should generate code like this:

worker.ts
import {
createFunction,
createProjection,
createWorker,
type IronflowProjection,
} from "@ironflow/node";
interface OrderData {
orderId: string;
total: number;
email: string;
}
// REACT: A recorded function that processes orders
// Every step is memoized and permanently recorded.
const processOrder = createFunction(
{
id: "process-order",
triggers: [{ event: "order.placed" }],
recording: true, // Enables time-travel debugging
},
async ({ event, step }) => {
const data = event.data as OrderData;
const order = await step.run("validate-order", async () => {
return { valid: true, orderId: data.orderId, total: data.total };
});
const payment = await step.run("process-payment", async () => {
return {
charged: true,
amount: order.total,
transactionId: `txn_${Date.now()}`,
};
});
await step.run("send-confirmation", async () => {
return { sent: true, email: data.email };
});
return { order, payment };
},
);
// DERIVE: A projection that computes order statistics
// Pure reducer — state is automatically persisted and queryable.
const orderStats = createProjection({
name: "order-stats",
events: ["order.placed"],
initialState: () => ({ totalOrders: 0, totalRevenue: 0 }),
handler: (
state: { totalOrders: number; totalRevenue: number },
event: { name: string; data: unknown },
) => ({
totalOrders: state.totalOrders + 1,
totalRevenue: state.totalRevenue + ((event.data as OrderData).total ?? 0),
}),
});
// Start the worker — functions and projections run together
const worker = createWorker({
functions: [processOrder],
projections: [orderStats as IronflowProjection],
});
worker.start().then(() => {
console.log("Worker started — listening for events");
});

Step 4: Emit Events

With the server and worker running, emit events to build up history:

Terminal window
ironflow emit order.placed --data '{"orderId": "order-1", "total": 99.99, "email": "customer@example.com"}'
ironflow emit order.placed --data '{"orderId": "order-2", "total": 49.50, "email": "another@example.com"}'
ironflow emit order.placed --data '{"orderId": "order-3", "total": 149.00, "email": "third@example.com"}'

Watch the worker terminal — you’ll see each event trigger the function and execute all three steps.


Step 5: Ask the AI to Query What Was Derived

How do I check the current state of the "order-stats" projection?
Show me the curl command and explain what I should see.

The AI should tell you:

Terminal window
curl -s http://localhost:9123/api/v1/projections/order-stats | jq '.state.state'
{
"totalOrders": 3,
"totalRevenue": 298.49
}

No aggregation queries. The projection derived this state automatically from the recorded events.


Step 6: Rewind Time

Every step of every function run was permanently recorded. Ask the AI:

How do I use Ironflow's time-travel debugging to replay a function run?

The AI should point you to:

Dashboard: Open http://localhost:9123, navigate to Runs, click any completed run, and use the timeline scrubber to drag back through the execution.

CLI:

Terminal window
ironflow run list
ironflow inspect <run_id> --replay

In replay mode: /l next frame, /h prev frame, g/G first/last, j/k navigate steps, Tab switch panels, q quit.


Step 7: Iterate with AI

Now ask the AI to extend the system with more Continuous History features:

Add error handling to the process-order function:
1. If validation fails, throw a NonRetryableError
2. Add retry configuration for the payment step
3. Add a step.sleep of 1 second between payment and confirmation

Or try adding event sourcing:

Create an entity stream for orders using Ironflow's event sourcing.
Append "order.placed", "order.shipped", and "order.delivered" events
to an entity stream keyed by orderId. Then show me how to read the
full history of a single order.

Verification Checklist

After the AI generates code, verify:

  • Each step has a unique, descriptive ID
  • Step functions are idempotent (safe to retry)
  • recording: true is set on functions you want to time-travel debug
  • Event data types match your expected payload
  • Projections use initialState as a function (not a plain object)
  • Error handling uses NonRetryableError where appropriate

What Just Happened?

You used an AI assistant to build a Continuous History system:

  1. Emit — Recorded events as permanent, immutable facts
  2. React — A durable function processed each event with memoized steps
  3. Derive — A projection automatically computed statistics from the event stream
  4. Rewind — Time-travel debugging let you replay any execution

The AI agent template ensures your assistant generates code that follows these patterns correctly.


What’s Next