withWorkflow

Configure webpack and Turbopack to transform workflow directives in Next.js.

Configures webpack and Turbopack loaders to transform workflow code ("use step" and "use workflow" directives).

Usage

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

next.config.ts
import { withWorkflow } from "workflow/next";
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);

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.

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:

apps/web/next.config.ts
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);

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.

Options

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

next.config.ts
import type { NextConfig } from "next";
import { withWorkflow } from "workflow/next";

const nextConfig: NextConfig = {};

export default withWorkflow(nextConfig, {
  workflows: {
    local: {
      port: 4000,
    },
    sourcemap: false,
  },
});
OptionTypeDefaultDescription
workflows.local.portnumberOverrides the PORT environment variable for local development. Has no effect when deployed to Vercel.
workflows.sourcemapboolean | 'inline' | 'linked' | 'external' | 'both''inline' (dev) / false (prod)Controls source maps on generated workflow bundles. See 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 virtual machine (VM) errors point at your source files) and to false in production, so function bundles stay small. The sourcemap option lets you change that:

ValueBehavior
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.
falseOmit 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 250 MB function size limit. The tradeoff is that workflow VM stack traces will reference generated code (for example, evalmachine.<anonymous>) rather than your source files.

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.

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.

The workflows.local options only affect local development. When deployed to Vercel, the runtime ignores local settings and uses the Vercel world automatically.

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.

next.config.ts
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;
}