Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/framework-shared-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@workflow/next": minor
"@workflow/nitro": minor
---

Add typed shared configuration support to the Next.js and Nitro integrations.
7 changes: 7 additions & 0 deletions .changeset/lazy-world-factories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@workflow/config": minor
"@workflow/world": minor
"@workflow/world-postgres": patch
---

Add typed Workflow configuration with module-based lazy World providers.
8 changes: 8 additions & 0 deletions .changeset/shared-config-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@workflow/builders": minor
"@workflow/cli": minor
"@workflow/core": minor
"workflow": minor
---

Bundle configured World modules and queue settings across runtime, build, and CLI entry points.
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,19 @@ prerequisites:
- /docs/getting-started/next
---

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]
export default withWorkflow(nextConfig); // [!code highlight]
```

<Callout type="warn">
Expand Down Expand Up @@ -82,7 +77,9 @@ Use the smallest directory that contains every workspace package imported by you

## Options

`withWorkflow` accepts an optional second argument to configure the Next.js integration.
Use [`workflow.config.ts`](/docs/foundations/configuration) for shared build and
Next.js settings. The optional second argument to `withWorkflow` overrides
environment variables and `workflow.config.ts`.

```typescript title="next.config.ts" lineNumbers
import type { NextConfig } from "next";
Expand All @@ -102,7 +99,7 @@ export default withWorkflow(nextConfig, {

| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `workflows.local.port` | `number` | — | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. |
| `workflows.local.port` | `number` | — | Sets the local Workflow server port. 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
Expand All @@ -123,19 +120,21 @@ In production, source maps are already off by default. Setting `sourcemap: false
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.
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 `withWorkflow` option >
`WORKFLOW_SOURCEMAP` > `workflow.config.ts` > per-bundle default.

<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 type { NextConfig } from "next";
import { withWorkflow } from "workflow/next";
import createNextIntlPlugin from "next-intl/plugin";

Expand Down
9 changes: 7 additions & 2 deletions docs/content/docs/v5/api-reference/workflow-nitro/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ related:
- /docs/getting-started/nitro
---

Nitro integration for Workflow SDK. The `workflow/nitro` entry point's default export is a [Nitro module](https://v3.nitro.build/guide/modules) — it has no callable API. You enable it by adding it to the `modules` array of your Nitro config and configure it via the `workflow` key.
Add the [`workflow/nitro` Nitro module](https://v3.nitro.build/guide/modules) to
transform workflow directives, build bundles, and register runtime routes.

## Usage

Expand All @@ -20,6 +21,10 @@ export default defineConfig({
});
```

Shared build and Nitro settings can also be placed in
[`workflow.config.ts`](/docs/foundations/configuration). Values under
`workflow` in `nitro.config.ts` take precedence.

When enabled, the module:

- Transforms `"use workflow"` and `"use step"` directives during bundling.
Expand All @@ -30,7 +35,7 @@ When enabled, the module:

## Module Options

Options are read from the `workflow` key of your Nitro config. The option type is exported as `ModuleOptions`:
The `workflow` key accepts the exported `ModuleOptions` type:

```typescript title="nitro.config.ts" lineNumbers
import { defineConfig } from "nitro";
Expand Down
104 changes: 104 additions & 0 deletions docs/content/docs/v5/foundations/configuration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: Configuration
description: Configure Workflow SDK with a typed workflow.config.ts file.
type: conceptual
summary: Configure the World, builds, and framework integration for your app.
prerequisites:
- /docs/foundations/workflows-and-steps
related:
- /docs/deploying/world/local-world
- /docs/deploying/world/postgres-world
- /docs/api-reference/workflow-next/with-workflow
---

Create `workflow.config.ts` in your application:

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

const config = {
world: "./workflow.world.ts",
build: {
dirs: ["workflows"],
sourcemap: false,
},
} satisfies WorkflowConfig;

export default config;
```

The World module default-exports a lazy provider:

```typescript title="workflow.world.ts" lineNumbers
import type { WorldProvider } from "workflow/config";
import { createWorld } from "@workflow/world-postgres";

const world: WorldProvider = () =>
createWorld({
connectionString: process.env.WORKFLOW_POSTGRES_URL!,
jobPrefix: "myapp_",
queueConcurrency: 50,
maxPoolSize: 52,
});

export default world;
```

<Callout type="info">
Next.js projects also wrap `next.config.ts` with `withWorkflow()`.
</Callout>

In a monorepo, place a config file in each application that needs its own
settings.

## Precedence

From highest to lowest priority:

1. Explicit CLI flags or framework options
2. Environment variables
3. `workflow.config.ts`
4. Built-in defaults

## World

`world` is a module specifier relative to `workflow.config.ts`, or a package
name. Its default export must satisfy `WorldProvider`. The provider runs only
when the application first needs its World.

## Worlds by Environment

Choose a World inside the factory based on the runtime environment:

```typescript title="workflow.world.ts" lineNumbers
import type { WorldProvider } from "workflow/config";
import { createLocalWorld } from "@workflow/world-local";
import { createWorld as createPostgresWorld } from "@workflow/world-postgres";

const world: WorldProvider = () => {
switch (process.env.NODE_ENV) {
case "production":
return createPostgresWorld({
connectionString: process.env.WORKFLOW_POSTGRES_URL!,
});
case "development":
case "test":
return createLocalWorld();
default:
throw new Error(`Unexpected NODE_ENV: ${process.env.NODE_ENV}`);
}
};

export default world;
```

## Integration Settings

Use `integration` for framework-specific settings. Set `type` to the framework
you are configuring:

{/* @skip-typecheck: mutually exclusive config fragments */}

```typescript
integration: { type: "nitro", typescriptPlugin: true, runtime: "nodejs24.x" }
```
1 change: 1 addition & 0 deletions docs/content/docs/v5/foundations/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"cancellation",
"serialization",
"idempotency",
"configuration",
"versioning"
],
"defaultOpen": true
Expand Down
2 changes: 2 additions & 0 deletions packages/builders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@
},
"dependencies": {
"@swc/core": "catalog:",
"@workflow/config": "workspace:*",
"@workflow/core": "workspace:*",
"@workflow/errors": "workspace:*",
"@workflow/utils": "workspace:*",
"@workflow/swc-plugin": "workspace:*",
"@workflow/world": "workspace:*",
"builtin-modules": "5.0.0",
"chalk": "5.6.2",
"enhanced-resolve": "catalog:",
Expand Down
Loading
Loading