Quickstart: your first scene
Seven steps from an empty account to a live copy of your app that you can open from a pull request.
This walks the shortest path from nothing to a scene you can open and click. It assumes you are adding Midstream to a real project, and it tells you what you should see after each step so you can tell where you are if something goes quiet.
Before you start
You need:
- A repository on GitHub, with an app that starts from a clean checkout. Midstream runs your install and start commands in a fresh container holding your repository at one commit, so anything else your app needs — migrations, seed data, a local database — has to come from those commands.
- Playwright end-to-end tests that pass in CI. Playwright is the only test framework the SDK supports, and version 1.40 or newer.
- Permission to install a GitHub App on the account or organization that owns the repository.
Pick one test to start with — the shorter and more reliable, the better. You can spread scenes across the suite once the loop is working.
1. Create your workspace and connect the repository
Go to midstream.studio and sign in with GitHub. GitHub is currently the only way to sign in.
A brand-new account goes straight to GitHub to install the Midstream GitHub App. Choose the account or organization that owns your repository, and grant access to the repositories you want to use. GitHub sends you back to Midstream, which asks you to name your workspace — a workspace is your team, and it owns your projects, members, and API keys. The name is pre-filled from the GitHub organization you just installed into.
Then create your first project. A project is one repository: pick it from the
list, give it a name, and Midstream creates it at
midstream.studio/your-workspace/your-project.
If the organization already has a Midstream workspace, you will land in that workspace instead of creating a new one, and you can add the project there.
What you should see: a project page saying Waiting for your first scene, naming your repository. Leave it open — it updates on its own when a capture arrives.
2. Install the SDK
In the repository holding your tests:
npm install --save-dev @midstream/sdkWhat you should see: @midstream/sdk in your devDependencies.
3. Mark a scene
Open the test you picked. Find the point where the screen shows the state you would want a reviewer to look at, and add a scene call there:
import { test, expect } from "@playwright/test";
import { midstreamScene } from "@midstream/sdk/playwright";
test("shopper sees the items in their cart", async ({ page }) => {
await page.goto("/products/espresso-beans");
await page.getByRole("button", { name: "Add to cart" }).click();
await page.goto("/cart");
await expect(page.getByRole("heading", { name: "Your cart" })).toBeVisible();
await midstreamScene(page, "cart-with-items");
});The function keeps its old name for now; it marks a scene.
Three things worth knowing about that line:
- The slug is the scene's identity. It becomes part of a hostname, so keep it short, kebab-case, and unique within the project. Change it later and you have started a new scene.
- It never fails your test. If Midstream is unreachable or something goes wrong recording the capture, the call warns on stdout and the test carries on.
- It does nothing locally. Run your suite on your laptop and this line is a no-op, so adding scenes does not slow down or change your normal runs.
What you should see: your test suite passes locally exactly as it did before, with no new output.
4. Add midstream.json
Midstream needs to know how to install, start, and test your app. Put a
midstream.json in the root of your repository:
{
"install": "npm ci",
"start": "npm start",
"test": "npx playwright test {{file}} -g \"{{grep}}\""
}installandstartare required.testis optional; leave it out and Midstream runsnpx playwright test {{file}} -g {{grep}}.{{file}}is replaced with the test file the scene was captured in, and{{grep}}with the chain of test titles that leads to it. Keep the quotes around{{grep}}— test titles contain spaces.- All three commands run from the repository root.
- Your
startcommand must make the app listen on the port in thePORTenvironment variable, which Midstream sets before running it.
If your app does not live at the repository root, point installDir and
startDir at the directory it does live in.
What you should see: nothing yet — this file is read during a deploy, not in CI.
5. Give CI the GitHub token
On GitHub Actions the SDK authenticates with the workflow's built-in
GITHUB_TOKEN, and works out which project you mean from the repository the
workflow is running in. Actions does not put that token in the environment for
you, so pass it to the step that runs your tests:
name: E2E
on: pull_request
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Nothing else changes about how your tests run. There is no separate Midstream job and no extra service to stand up.
6. Open a pull request
Commit the SDK dependency, the scene call, and midstream.json, push the
branch, and open a pull request. Your existing workflow runs the suite; when
the test reaches the scene call, the SDK registers the capture.
What you should see, in this order:
- Your test job passes as usual.
- Within a minute or so of the suite finishing, a check named Midstream Scenes appears on the pull request, saying how many scenes the change touches. Updates are grouped per commit, so a suite that captures a hundred scenes produces one update rather than a hundred.
- Alongside it, a deployment link into Midstream's view of that pull request.
- On the project page you left open in step 1,
cart-with-itemsappears. The project page shows one branch at a time and opens on your default branch, so your new scene shows up behind a Scenes on another branch banner — click View that branch to see it.
7. Open the instance
Follow the deployment link, or go to the project page and click the scene.
The first open is the slow one. Midstream clones your repository at that commit, runs your install command, starts your app, and runs your test up to the scene call. That takes minutes, not seconds, and you get a loading page while it happens. When the test reaches the scene, the browser session at that moment — the URL, cookies, local storage, session storage — is handed to your browser, and you land in the running app at the marked moment.
Click around. It is your app, built from the commit under review.
What you should see: your app, at the moment you marked, with a small Midstream toolbar floating over it.
Later opens of the same instance are quick, and every person who opens the scene gets their own copy.
If nothing shows up
Work down this list in order.
- No scene on the project page. The capture never reached us. Check the
test job's log for a line beginning
[Midstream]— the SDK warns rather than failing, so a problem registering the capture shows up there and nowhere else. The two usual causes are a missingGITHUB_TOKENin the test step and a project that is not linked to the repository the workflow ran in. - The test never got there. A scene is only captured if the test actually reaches the call. If the test failed earlier in the run, there is nothing to capture.
- A scene, but no check on the pull request. The check is attached to the head commit of an open pull request. If you pushed the branch before opening the pull request, push another commit.
- The instance fails to come up. The error page names the stage it failed
at. The most common ones are a
midstream.jsonthat is missing or not valid JSON, an install or start command that does not work from a clean checkout, and an app that never starts listening onPORT. Your project's health view shows each attempt with its output, and lets you retry.
Next
- Add scenes to the moments that actually get argued about in review — one per moment worth looking at.
- Before you mark scenes widely, read how a capture handles sessions. Opening an instance replays the session the test was in, so scenes belong in tests that use test accounts and seeded data, never tests that sign in to real production data.
- Invite the people who should be looking — reviewers, designers, PMs. Opening an instance requires membership of your workspace.