Paste the URL on the home page, pick a branch or tag, deploy. Framework, port and build commands are detected and stay editable. Each deployed commit gets its own URL, private until you expose it.
What each preset runs
A framework named in the manifest wins over its build tool, which wins over the bare runtime. Install and Build are editable in Settings → Build; the start command is not.
| Preset | Install · Build | Runs | Port |
|---|---|---|---|
static |
none | nginx on the repo root or Output dir | 8080 |
vite, vue |
npm install · npm run build |
nginx on dist |
8080 |
astro, svelte, angular |
same | nginx on dist |
4321, 5000, 4200 |
react |
same | nginx on build |
3000 |
node |
same | your server, npm run start |
8080 |
nextjs, nuxt, remix, sveltekit |
same | your server | 3000 |
go |
go mod download -x · go build -v -o /out/app . |
the binary alone | 8080 |
fastapi |
pip install -r requirements.txt |
uvicorn main:app |
8000 |
flask (port 5000) and django (8000) share the Python builder.
The traps
- Go ships the binary alone: embed templates and static files with
//go:embed. The Build command must write/out/app, the only path copied.CGO_ENABLED=1in the environment switches to Debian-based images. - Python installs
requirements.txtand nothing else, so it must listuvicornorgunicorn. Apyproject.toml-only repo is detected, then fails at install: set Install topip install -e .. Entry points are fixed:main:app,app:app,config.wsgi:application. - Static output must hold an
index.html, or the build fails and names the folder. nginx answersindex.htmlfor every path without a file, so there is no custom 404 page. AVITE_variable is baked in at build time: keep its Include in build switch on (the default), rebuild after changing it; it is public. - No server, no backends. The nginx presets cannot use Postgres or the bucket. A Vite repo whose
startscript runs your own server is detected asnodeinstead.
Port and health check
Port is injected as PORT and wins over your own; listen on it, on all interfaces. Health check takes a path such as /healthz, empty means a TCP probe; a failing path blocks readiness and restarts the container.
Versions and monorepos
- Node: the Node picker (18 to 24), then
.nvmrc,.node-version,engines.node(first major of a range), then 22. - Python:
runtime_versionviaupdate_settings(3.10 to 3.13; no dashboard picker),.python-version,runtime.txt, then 3.12. - Go: the
goline ofgo.mod, else 1.24. - Monorepo: Root directory in Settings → Build.
Without an account
A public repo deploys without logging in, as a temporary project: 72 hours, then it stops and is removed, data included. Your first action (branch lookup, deploy, nickname) creates a guest with one temporary project; reading stores nothing. Log in with GitHub or Google to keep it: a live project turns permanent when the slot is free, otherwise press Make permanent under Project lifetime. A private repository needs Authorize private repos, a GitHub App, so an account.
Limits
- One container per app: one port, one replica, 1 CPU, 1 GiB of memory. No workers, no cron.
- No deploy on push, no webhook: a build starts from the dashboard or from an agent.
- 20 builds per day per account, whoever starts them.
- A free account holds one permanent project and one temporary one; guest sign-ups are rate-limited per network.
- Public alpha, no SLA: keep your own backups.