Skip to main content

Getting a project onto FlowWright

flow init

flow init

Reads the project first, then writes a pipeline.ts that matches it.

✓ created pipeline.ts
detected: npm · lint, typecheck, test, build

next: flow run

What it detects:

SignalEffect
pnpm-lock.yaml / yarn.lock / package-lock.jsonPicks the package manager and the right install command
packageManager in package.jsonOverrides the lockfile
name in package.jsonBecomes the pipeline name, scope stripped
Scripts named lint, typecheck, test, buildEach becomes a stage

The install command follows the lockfile: npm ci for npm, install --frozen-lockfile for pnpm and yarn, plain install when there's no lockfile at all. Checks depend on install, build depends on the checks.

In a directory with no package.json, you get something runnable to edit rather than an error:

import { pipeline, stage, sh } from "@flowwright/core";

export default pipeline({
name: "bare",
stages: [
stage("Hello", async () => {
await sh`echo "hello from FlowWright"`;
}),
],
});

flow init won't overwrite an existing file — it exits 1 instead. Use -f to write somewhere else:

flow init -f pipelines/release.ts

--plugins

flow init --plugins

Emits the plugin-node equivalent instead of spelled-out stages:

import { pipeline, group } from "@flowwright/core";
import { nodeStages } from "@flowwright/plugin-node";

export default pipeline({
name: "api",
stages: [...group("ci", nodeStages({ packageManager: "pnpm" }))],
});
✓ created pipeline.ts
detected: pnpm

install: pnpm add -D @flowwright/plugin-node

next: flow run

It needs a package.json to work with. Without one it writes the plain pipeline and tells you:

! --plugins needs a Node project; wrote a plain pipeline instead

flow migrate

flow migrate jenkinsfile ./Jenkinsfile
flow migrate ./Jenkinsfile # the jenkinsfile keyword is optional
Best-effort, review the output

migrate is a regex scan over Groovy, not a Jenkins parser. It reads well-formed declarative pipelines and gives up gracefully on the rest. Treat the result as a first draft — read every line before running it.

Migration report · ./Jenkinsfile

4 stages: Build, Lint, Test, Deploy
5 shell steps

difficulty: easy

--- suggested pipeline.ts ---
// Generated by `flow migrate jenkinsfile` — best-effort; review before use.

import { pipeline, stage, sh, onBranch } from "@flowwright/core";

const env = {
"CI": "true",
};

export default pipeline({
name: "migrated-pipeline",
concurrency: 2,
stages: [
stage("Build", {
id: "build",
run: async () => {
await sh.raw("pnpm install", { env });
await sh.raw("pnpm build", { env });
},
}),
],
});

The report comes first — stage count, step count, and a difficulty estimate — so you can judge whether the conversion is worth trusting before reading it.

Note that migrated steps use sh.raw, which runs through a shell. That's the honest translation of a Jenkins sh step, but converting them to sh([...]) argv arrays as you review removes a layer of quoting.

Write it to a file instead of stdout with --out:

flow migrate jenkinsfile ./Jenkinsfile --out pipeline.ts

flow export

Prints a CI config that calls FlowWright. Your pipeline logic stays in pipeline.ts; the exported file is just the wrapper that invokes it.

flow export github-actions
name: CI
on: [push, pull_request]
jobs:
flow:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version: 24
- run: npx @flowwright/cli run
flow export gitlab-ci
flow:
image: node:24
script:
- npx @flowwright/cli run
flow export jenkins
pipeline {
agent { docker { image 'node:24' } }
stages {
stage('FlowWright') {
steps {
sh 'npx @flowwright/cli run'
}
}
}
}

Each is printed to stdout with a leading comment naming where it belongs — redirect it yourself:

flow export github-actions > .github/workflows/flowwright.yml

These are starting points, meant to be edited. They're deliberately minimal: one job, one command. Caching, matrices and artifact upload are yours to add — and much of it you may not need, since FlowWright already handles caching and parallelism inside the pipeline.

flow run picks the right output format automatically once it's running in CI. See Reporters, and Running in CI for the provider-side half — caching, test reports and what each provider does with the output.