Connect your app server
Give Dyno the command you already use to start your app and its URL. Your server still handles routes, assets, API calls, and hot reload.
webServer: { command: 'npm run dev', url: 'http://127.0.0.1:3000', ready: 'Listening on', reuseExistingServer: !process.env.CI,}The server must log after it starts listening. ready can be a string or RegExp matching that message. Output triggers an HTTP HEAD check; any response, including a 401 or 404, confirms the server is up. There’s no fixed startup sleep.
Start and stop
Section titled “Start and stop”Dyno reuses a responding server only with reuseExistingServer: true and leaves it running afterward. Otherwise, it starts command in cwd with env. Use a shell string or an argv array such as ['node', 'server.js'].
When a run ends or fails, Dyno stops the processes it started, including descendants. A bounded grace period comes before forceful termination. Reused servers and manually opened browsers remain yours.
How the app reaches the browser
Section titled “How the app reaches the browser”The browser loads Dyno’s gateway, which forwards app requests and WebSockets to webServer.url. The app fills the main window. Tests load in a companion window and read the app’s DOM directly; a small injected script reports readiness and errors and hosts the reporter iframe. Your app needs no test imports.
Redirects to the app are rewritten to the gateway origin. Dyno translates same-origin Origin/Referer headers and matching cookie domains, preserving cookie security attributes. External redirects stay external.
The app receives DYNO_URL, the gateway origin. Use it as your public URL for OAuth or WebAuthn: browser credentials contain that origin, while the upstream receives its own Host. Root-relative URLs work best.
If the app blocks the runner
Section titled “If the app blocks the runner”Dyno preserves CSP and isolation headers and uses an existing script nonce when available. Give your app an explicit test configuration if it blocks injection, the reporter iframe, or same-origin window access. Changing isolation policy or navigating cross-origin can disconnect the companion and is unsupported.
The gateway accepts UTF-8 HTML, including gzip, deflate, and Brotli, up to 10 MB decoded. See current limits for origin and browser requirements.