Integrations
GitHub workflow
Run user flows on every pull request and post the Markdown report as a sticky PR comment.
With a few steps your user flows run on every pull request and the Markdown report is posted as a comment. Reviewers see the performance impact of a change next to the code.

If GitHub Actions are new to you, start with the GitHub Actions features page. The action used here is published on the marketplace.
1. Make sure the flow runs locally#
The workflow needs a working .user-flowrc.json and at least one flow, as set up in the Quick start. Verify the setup with a dry run that prints to the console:
npx user-flow collect --dryRun --format stdoutAdd --rcPath path/to/.user-flowrc.json if the rc file is not in the repository root. When the steps show up without errors you are ready.
2. Generate the workflow#
init can write the workflow file for you:
npx user-flow init --generateGhWorkflowThis creates .github/workflows/user-flow-ci.yml. A complete, up-to-date version of it looks like this:
name: user-flow-ci
on:
pull_request:
jobs:
user-flow:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Install Chrome for Puppeteer
run: npx puppeteer browsers install chrome
- name: Run user flows
uses: push-based/user-flow-gh-action@v0.3.2
with:
# defaults to .user-flowrc.json in the repository root
rcPath: .user-flowrc.jsonWhat the pieces do:
permissionslets the action comment on the pull request.npx puppeteer browsers install chromedownloads the Chrome build Lighthouse needs. Runners do not ship a compatible build.push-based/user-flow-gh-actionrunscollectin CI mode, so prompts are off and reports are not opened, and attaches the Markdown summary to the PR.
3. Test the setup#
Open a pull request. The workflow appears in the checks of the PR and runs your flows:
When it finishes, the Markdown report is attached to the pull request as a comment:
Alternative: post the report yourself#
If you need more control, run the CLI directly and post the md report with a sticky comment action. This is what the user-flow repository does for its own github-report example. The rc file requests only the Markdown format:
{
"collect": {
"url": "https://coffee-cart.netlify.app/",
"ufPath": "./examples/github-report/user-flows"
},
"persist": {
"outPath": "./examples/github-report/measures",
"format": ["md"]
}
}The workflow collects the report and hands the file to marocchino/sticky-pull-request-comment, which replaces its previous comment on every run instead of adding a new one:
name: user-flow-md-report
on:
pull_request:
jobs:
report:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Collect report
run: npx user-flow --rcPath ./examples/github-report/.user-flowrc.json --openReport false
- name: Add report as PR comment
uses: marocchino/sticky-pull-request-comment@v2
with:
hide_and_recreate: true
header: user-flow-report
path: ./examples/github-report/measures/*.md
Measuring a preview deployment#
Pass the URL of the deployment under test to the CLI instead of hard-coding it in the rc file. Most hosting providers expose the preview URL as an output of their deploy step:
- name: Run user flows against the preview
run: npx user-flow --url ${{ steps.deploy.outputs.url }} --format md --format htmlUpload the HTML report as a workflow artefact if you want the full Lighthouse UI for a run:
- uses: actions/upload-artifact@v4
with:
name: user-flow-reports
path: measures