wait-on: Gate CI Steps on Service Readiness
wait-on http://localhost:3000 blocks until that URL responds, then exits 0 so the next CI step can safely run.
Starting a server in the background and immediately running tests races the boot. wait-on polls a resource (URL, port, or file) until it is available, giving you a clean readiness gate.
What it does
wait-on polls one or more resources until they become available, then exits 0; if the timeout is hit first it exits non-zero. Resources are given as URLs: http:// and https:// wait for a successful (2xx) response, http-get:// forces a GET, tcp:host:port waits for the port to accept connections, and a plain path waits for a file to exist.
Common usage
wait-on http://localhost:3000/health
wait-on -t 60000 http://localhost:3000 # 60s timeout
wait-on tcp:localhost:5432 # wait for a port
# wait for several resources at once
wait-on http://localhost:3000 tcp:localhost:6379Options
| Flag / resource | What it does |
|---|---|
| http://host:port/path | Wait for a 2xx HTTP(S) response |
| http-get://... | Force a GET instead of the default HEAD |
| tcp:host:port | Wait for the TCP port to accept connections |
| -t, --timeout <ms> | Give up after this many milliseconds |
| -i, --interval <ms> | Poll interval |
| -v, --verbose | Log each poll attempt |
In CI
Put wait-on between "start the server" and "run the tests" so the suite never races a booting service. Note wait-on issues a HEAD by default; if your health endpoint only answers GET, use the http-get:// form. Set a realistic -t so a genuinely stuck service fails fast instead of at the runner timeout.
Common errors in CI
Error: Timed out waiting for: http://localhost:3000 means the resource never became ready within -t; the service failed to start, bound a different port, or only answers GET (try http-get://). If wait-on returns immediately as ready but tests still fail, the port is open but the app is not fully initialized; wait on a real health URL rather than a bare tcp: port.