## Hatchet TypeScript V1 Migration Guide

> **Warning:** This guide covers migrating from Hatchet **v0** to **v1**. v0 has since been
>   removed and everything now runs on v1, so this page is kept for historical
>   reference only and is no longer relevant.

This guide will help you migrate Hatchet workflows from the V0 SDK to the V1 SDK.

#### Introductory Example

First, we've exposed a new `hatchet.task` method in the V1 SDK for single function tasks.

```typescript
import { hatchet } from '../hatchet-client';

// (optional) Define the input type for the workflow
export type SimpleInput = {
  Message: string;
};

export const simple = hatchet.task({
  name: 'simple',
  retries: 3,
  fn: async (input: SimpleInput) => {
    return {
      TransformedMessage: input.Message.toLowerCase(),
    };
  },
});
```

DAGs are still defined as workflows, but they can now be declared using the `hatchet.workflow` method.

```typescript
// First, we declare the workflow
export const dag = hatchet.workflow({
  name: 'simple',
});
```

And you can bind tasks to workflows as follows:

```typescript
// Next, we declare the tasks bound to the workflow
const toLower = dag.task({
  name: 'to-lower',
  fn: (input) => {
    return {
      TransformedMessage: input.Message.toLowerCase(),
    };
  },
});
```

You can now run work for tasks and workflows by directly interacting with the returned object.

```typescript
const res = await dag.run({
  Message: 'hello world',
});
```

There are a few important things to note when migrating to the new SDK:

1. The new SDK uses a factory pattern (shown above) for creating tasks and workflows, which we've found to be more ergonomic than the previous SDK.
2. The old method of defining tasks will still work in the new SDK, but we recommend migrating over to the new method shown above for improved type checking and for access to new features.
3. New features of the SDK, such as the new durable execution features rolled out in V1, will only be accessible from the new `TaskDeclaration` object in the new SDK.

Since the old pattern for declaring tasks will still work in the new SDK, we recommend migrating existing tasks to the new patterns in V1 gradually.

#### Fanout Example

The new SDK also provides improved type support for spawning child tasks from around the codebase. Consider the following example:

First, we declare a child task:

```typescript
import { hatchet } from '../hatchet-client';

type ChildInput = {
  N: number;
};

export const child = hatchet.task({
  name: 'child',
  fn: (input: ChildInput) => {
    return {
      Value: input.N,
    };
  },
});
```

Next, we spawn that child from a parent task:

```typescript
type ParentInput = {
  N: number;
};

export const parent = hatchet.task({
  name: 'parent',
  fn: async (input: ParentInput, ctx) => {
    const n = input.N;
    const promises = [];

    for (let i = 0; i < n; i++) {
      promises.push(child.run({ N: i }));
    }

    const childRes = await Promise.all(promises);
    const sum = childRes.reduce((acc, curr) => acc + curr.Value, 0);

    return {
      Result: sum,
    };
  },
});
```

In this example, the compiler knows what to expect for the types of `input` and `ctx` for each of the tasks, as well as the type of the input of the `child` task when spawning it from the `parent` task.
