---
title: withWorkflow
description: Configure webpack/turbopack to transform workflow directives in Next.js.
type: reference
summary: Wrap your Next.js config with withWorkflow to enable workflow directive transformation.
prerequisites:
  - /docs/getting-started/next
---

# withWorkflow



Configures webpack/turbopack loaders to transform workflow code (`"use step"`/`"use workflow"` directives)

## Usage

To enable `"use step"` and `"use workflow"` directives while developing locally or deploying to production, wrap your `nextConfig` with `withWorkflow`.

```typescript title="next.config.ts" lineNumbers
import { withWorkflow } from "workflow/next"; // [!code highlight]
import type { NextConfig } from "next";
 
const nextConfig: NextConfig = {
  // … rest of your Next.js config
};

// not required but allows configuring workflow options
const workflowConfig = {} 

export default withWorkflow(nextConfig, workflowConfig); // [!code highlight]
```

<Callout type="warn">
  If a package in `serverExternalPackages` contains workflow code (`"use step"`,
  `"use workflow"`, or serialization classes), `withWorkflow()` automatically
  removes it from `serverExternalPackages` for the current build and prints a
  warning. Workflow still compiles the package so its directives are transformed.
  Remove that package from `serverExternalPackages` in your
  `next.config` to silence the warning.
</Callout>

### Monorepos and Workspace Imports

By default, Next.js detects the correct workspace root automatically. If your Next.js app lives in a subdirectory such as `apps/web` and workspace resolution is not working correctly, you can set `outputFileTracingRoot` as a workaround:

```typescript title="apps/web/next.config.ts" lineNumbers
import { resolve } from "node:path";
import type { NextConfig } from "next";
import { withWorkflow } from "workflow/next";

const nextConfig: NextConfig = {
  outputFileTracingRoot: resolve(process.cwd(), "../.."),
};

export default withWorkflow(nextConfig);
```

<Callout type="info">
  Use the smallest directory that contains every workspace package imported by your workflows. If your app already lives at the repository root, you do not need to set `outputFileTracingRoot`.
</Callout>

## Options

`withWorkflow` accepts an optional second argument to configure the Next.js integration.

```typescript title="next.config.ts" lineNumbers
import type { NextConfig } from "next";
import { withWorkflow } from "workflow/next";

const nextConfig: NextConfig = {};

export default withWorkflow(nextConfig, {
  workflows: {
    local: {
      port: 4000,
    },
    sourcemap: false,
  },
});
```

| Option                 | Type                                                      | Default                           | Description                                                                                             |
| ---------------------- | --------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `workflows.local.port` | `number`                                                  | —                                 | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. |
| `workflows.sourcemap`  | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` (dev) / `false` (prod) | Controls source maps on generated workflow bundles. See [Source maps](#source-maps) below.              |

### Source maps

The step bundle and intermediate workflow bundle default to `'inline'` source maps **in development** — so stack traces from step errors and workflow VM errors point at your source files — and to **`false` in production**, so function bundles stay small. The `sourcemap` option lets you change that:

| Value               | Behavior                                                                           |
| ------------------- | ---------------------------------------------------------------------------------- |
| `true` / `'inline'` | Base64-encode the source map and append it to the bundle (default in development). |
| `'linked'`          | Write a separate `.map` file and add a `sourceMappingURL` comment.                 |
| `'external'`        | Write a separate `.map` file without the comment.                                  |
| `'both'`            | Emit both inline and external source maps.                                         |
| `false`             | Omit source maps entirely.                                                         |

In production, source maps are already off by default. Setting `sourcemap: false` explicitly also turns them off in development, and it drops the inline source map from every bundle while skipping the source-map-support runtime shim on the Vercel step function (the same behavior production gets by default) — the main lever for staying under the Vercel 250MB function size limit. The tradeoff is that workflow VM stack traces will reference generated code (e.g. `evalmachine.<anonymous>`) rather than your source files.

<Callout type="info">
  Setting `sourcemap` explicitly affects **all** generated bundles (steps, workflows, webhook). The legacy `WORKFLOW_EMIT_SOURCEMAPS_FOR_DEBUGGING=1` environment variable is narrower — it only toggles source maps on the final workflow wrapper and webhook bundle (which default to off). It continues to work, but new code should use the `sourcemap` option or the `WORKFLOW_SOURCEMAP` environment variable instead.
</Callout>

The option can also be set via the `WORKFLOW_SOURCEMAP` environment variable, which accepts the same values plus `'0'` / `'1'` as aliases for `false` / `true`. Precedence is: explicit config > `WORKFLOW_SOURCEMAP` > the environment-aware default (`'inline'` in development, `false` in production). Development is detected from `next dev` / `NODE_ENV=development`, so the config option and the env var both let you force either behavior in either environment.

<Callout type="info">
  The `workflows.local` options only affect local development. When deployed to Vercel, the runtime ignores `local` settings and uses the Vercel world automatically.
</Callout>

## Exporting a Function

If you are exporting a function in your `next.config` you will need to ensure you call the function returned from `withWorkflow`.

```typescript title="next.config.ts" lineNumbers
import { NextConfig } from "next";
import { withWorkflow } from "workflow/next";
import createNextIntlPlugin from "next-intl/plugin";

const withNextIntl = createNextIntlPlugin();

export default async function config(
  phase: string,
  ctx: {
    defaultConfig: NextConfig
  }
): Promise<NextConfig> {
  let nextConfig: NextConfig | typeof config = {};

  for (const configModifier of [withNextIntl, withWorkflow]) {
    nextConfig = configModifier(nextConfig);

    if (typeof nextConfig === "function") {
      nextConfig = await nextConfig(phase, ctx);
    }
  }
  return nextConfig;
}
```


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)