---
title: "Flow Like Water | DJ Petersen"
description: "A TypeScript library that turns brittle multi-step scripts into resumable state machines with retries and serializable state."
canonical: "https://www.thedjpetersen.com/projects/flow-like-water/"
---

[Projects](https://www.thedjpetersen.com/projects)

# Flow Like Water

A TypeScript library for multi-step tasks, with retries, conditions, and state you can save.

2023TypeScript / Node.js / Jest[Source on GitHub](https://github.com/thedjpetersen/flow-like-water)Workflow 7 tasksDetails With a retryWithout a failure**Complete6 completed, 1 skipped10.2s

A scripted example. Select a task to see its state, or drag the timeline to move through the run.

## Working with tasks

### Retries

Give each task its own retry limit and delay. A delay function can add exponential backoff.

```
new Task({
  id: 'deploy-pod',
  execute: () => deployPod(),
  retries: 5,
  waitTime: (attempt) =>
    Math.min(1000 * 2 ** attempt,
      30000),
});
```

### Conditions

Skip work that's already done. Return a task ID from execute to choose the next step.

```
new Task({
  id: 'create-namespace',
  checkCondition: async () =>
    !(await namespaceExists()),
  execute: async () => {
    await createNamespace();
    return 'deploy-app';
  },
});
```

### Saved state

Serialize the run, store it, and use that record to decide which task to resume later.

```
const state = flow
  .getSerializedState();

await save(state);

// Later, resume an unfinished task.
await flow.runTask(taskId);
```

Examples are abbreviated; service and storage helpers are omitted. The [repository](https://github.com/thedjpetersen/flow-like-water) has the full API.
