Web is in alpha. To add it to your organization, email [email protected].
Create a Web app
In the dashboard, click Create app, pick Web, and optionally enter your first deployed HTTPS URL and commit SHA. Web apps don’t need a package or bundle ID. To add a URL later, click Upload build on the Builds page, pick the Web app, and enter the HTTPS URL. From the CLI:revyl init doesn’t detect Web frameworks, package managers, or preview hosts, create a Web
app, or write a Web recipe. Add the app to .revyl/config.yaml yourself:
build.framework, and a Web recipe can sit beside ios and android recipes.
Build a Web bundle
Add a recipe with your project’s package manager and build command:--remote is also accepted. --local uses your installed
toolchain and still uploads the result. Both paths use the same recipe, app association, and
build lifecycle. Remote builds require a Git commit and record the original HEAD even when the
source includes local edits.
output_path must be one dedicated project-relative output directory, without globs. Only its
contents enter the .tar.zst bundle, not the source checkout. Symlinks, special files, .git,
.revyl, .env*, and credential files are rejected. Compressed and unpacked data are each
limited to 200 MiB, with at most 20,000 archive entries and 1,024-byte paths. Static output
needs an index.html at its root.
revyl build requires explicit build_commands and output_path; it never guesses a build
command or turns an app-only profile into a recipe. Building a URL-only profile fails with
profile <name> is URL-only; add build_commands and output_path, or register previews with revyl build upload --url.
Server-rendered apps
Package the server and all of its runtime dependencies inside the output directory, and give a start command relative to the bundle root:0.0.0.0) at the configured port, not only
localhost or 127.0.0.1; the browser reaches it at http://revyl-app.localhost:<port>. Revyl sets
HOSTNAME=0.0.0.0 and PORT for the process. The app is ready when GET <healthcheck>
returns any 2xx or 3xx status; redirects aren’t followed. A localhost-only app fails the health
check with couldn't connect to revyl-app:<port>. The defaults are port 3000, healthcheck
/, and a 60-second startup timeout (10 to 600 seconds allowed).
Without run.start, the session serves static output. A request for a missing path without a
file extension gets <path>.html when that file exists, otherwise the root index.html, so
client-side routes and clean URLs load on reload or deep link. A missing asset such as
/app.js still returns 404.
run.env_keys names existing plaintext organization launch variables, and run.secret_names
names encrypted ones. These are names, never values or KEY=VALUE assignments. They’re
injected only into the app process when the session starts it, not into the browser or the
build. Build-time settings stay in env and secrets, as for mobile recipes. Never bake
secrets into the output directory.
Register a preview from CI
- App.
--app <name-or-id>selects the Web app. Without it, the command readsbuild.profiles.<name>.web.app_id. Profiles that name different Web apps need--app. - URL. Must be HTTPS, with no credentials, query string, or fragment. Revyl doesn’t fetch anything when it registers the URL.
- Pull request. The command stores the same CI metadata on the build as mobile uploads do.
GitHub Actions and Buildkite are detected automatically. On any other runner, pass
--repo owner/name --commit <full PR head SHA>, and add--pr <number>to choose the pull request explicitly.--commitrequires--repo. - Branch.
--branch <name>registers the build on that Revyl branch, creating it if needed; without it, the build lands on the app’s default branch. Give each pull request its own branch (for example--branch pr-42) so previews never become what the default branch opens. - Latest. Registering the same URL and commit again returns the existing build
(
"was_reused": true) and makes it its branch’s latest.
--file, --header, --version, --pin, --set-current, --no-set-current,
--preview, and --name are rejected by build upload --platform web.
pr_review.build.profile can name a profile with a complete Web build recipe. Naming a URL-only
Web profile there is rejected with the same URL-only error.
Open a build
--branch <name> opens the newest build on that branch, --all-branches the newest across
every branch, and --build-version-id a specific build. --url registers a URL (on
--branch when given) and opens it in one step. --build-selection inherit and pinned
aren’t available for Web. See Sessions to start one from the
dashboard.
When a bundle’s app fails
If a bundle’s app can’t start, or exits during the session, the session fails with a specific reason, for example “Your app exited before it was ready (exit code 1)”, a health check that didn’t return 2xx or 3xx in time, a bundle that didn’t match the build’s size or checksum, or a missing launch variable named inrun.env_keys or run.secret_names. The CLI, MCP tools, and
the session’s failure state in the app all show the reason.
Revyl keeps the last 64 KiB of the app’s combined stdout and stderr. Members of the organization
see the last lines in the live session’s failure state and in the session report, and can
download the whole log from either. Public report links show only the reason. Values of the
variables injected through run.env_keys and run.secret_names, and token-shaped strings
such as JWTs and signed-URL signatures, are redacted before the output leaves the session.