CLI tool
jeffbski/wait-on avatar
jeffbski/wait-on

wait-on for Node.js startup dependencies and shutdown gates

wait-on is a cross-platform command line utility and Node.js API which will wait for files, ports, sockets, and http(s) resources to become available

1,988 stars89 forksJavaScriptMIT

At a glance

What is it?
wait-on is a Node.js CLI and API for blocking scripts until files, TCP services, Unix sockets, HTTP endpoints, or commands meet specified conditions. It fits startup orchestration and shutdown workflows, but polling requires explicit timeouts and careful endpoint selection.
Who is it for?
Adopt wait-on when a Node.js process needs a small, cross-platform gate for several local or remote resources. Do not choose it as a substitute for an application health check that validates internal state.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

wait-on solves cross-platform readiness sequencing

wait-on addresses scripts that start before their dependencies are usable. Instead of embedding arbitrary sleeps or writing separate retry logic for Linux, macOS, and Windows, a script can ask wait-on to watch one or more resources and exit successfully only after they satisfy the requested condition. The intended users are Node.js developers, test harnesses, deployment scripts, and local development workflows that need deterministic ordering.

The supported resource types cover several common dependencies. A plain path or a `file:` resource represents a regular file. `tcp:` checks whether a TCP port is listening, while `socket:` checks a Unix domain socket. HTTP and HTTPS prefixes probe web endpoints, and `command:` runs an arbitrary command that must exit with code 0. All supplied resources must be ready before wait-on exits with code 0.

Reverse mode changes the condition from availability to unavailability. That makes the same utility useful for shutdown sequencing, where a script should wait until a service has stopped listening before continuing. This is a narrower behavior than a full deployment orchestrator: wait-on gates execution, while the commands before and after it still belong to the surrounding script.

File handling is more deliberate than simple existence polling. wait-on can wait for a file to stop growing before treating it as available, which suits artifacts that are still being copied or written. The CLI also exposes a stability window so a resource must remain unchanged or available for a defined period before success. This reduces some false positives, although the README does not claim that filesystem monitoring detects semantic completeness such as a valid archive or fully flushed database.

Polling, HTTP validation, and timeout behavior in wait-on

wait-on repeatedly checks resources until the aggregate condition is satisfied or the operation fails. The polling interval defaults to 250 milliseconds, and an initial delay can be set when a dependency should not be contacted immediately. Multiple resources are supplied as positional arguments, and the process reports success only after all of them meet the requested state.

HTTP probes have an important method distinction. `http:` and `https:` send `HEAD` requests and require a 2XX response after redirects. `http-get:` and `https-get:` send `GET` requests, which is the appropriate choice when a server does not implement `HEAD` or when readiness depends on the response body. The README specifically notes that many servers answer `HEAD` with `404` or `405`, so choosing the shorter default probe without checking the server can produce a false failure.

By default, HTTP success means any 2XX status. The `--status-codes` option changes that contract and accepts an exact code, an inclusive range, or a comma-separated list. For example, `--status-codes 200-499` treats every response in that interval as successful. This is useful when a probe path intentionally returns `404` while the broader service is ready, but it can also conceal an endpoint that is reachable yet unhealthy if the range is too broad.

Time control matters in automation. The global `--timeout` defaults to infinity, while `--httpTimeout` defaults to 0, which leaves request timeout behavior to the operating system or library defaults. TCP connections have a separate `--tcpTimeout` default of 300 milliseconds. A workflow without a finite overall timeout can wait forever if its readiness assumption is wrong. The default connection concurrency is `Infinity`; setting `--simultaneous 1` serializes attempts to a resource when connection pressure needs to be limited.

On interruption or timeout, wait-on returns a non-zero exit code. In a shell chain using `&&`, that prevents the next command from running, which makes the exit status suitable as a gate.

Installing wait-on and running a first startup gate

wait-on supports Node.js versions that are active or in maintenance. The current package manifest raises the concrete requirement to `>=20.0.0`. For a project-local installation, use the local npm form documented by the README.

bash
npm install wait-on

This adds `wait-on` to the current project's dependencies and makes the CLI available through the project's local execution environment. A global installation is also documented:

bash
npm install -g wait-on

A minimal first use waits for a TCP port before running a command. The README uses this shell pattern to make the next action conditional on successful readiness.

bash
wait-on tcp:4000 && NEXT_CMD

`tcp:4000` checks whether something is listening on TCP port 4000. `NEXT_CMD` is the command to run after the port becomes available.

For a web service whose readiness endpoint supports `GET` but not `HEAD`, use the explicit GET form:

bash
wait-on http-get://localhost:8000/foo && NEXT_CMD

The `-get:` form sends an HTTP `GET` request and waits for a 2XX response. The README also documents this web probe:

bash
wait-on https-get://myserver/foo && NEXT_CMD

A command-based health check can be used instead of a resource prefix:

bash
wait-on command:./health-check.sh && NEXT_CMD

Here, wait-on succeeds only when the script exits with code 0. The README's usage examples also show combining two files in one gate:

bash
wait-on f1 f2 && NEXT_CMD

Both resources must be ready before `NEXT_CMD` runs.

Reverse mode and wait-on configuration boundaries

Reverse mode waits for resources to become unavailable. That makes it possible to place a shutdown check in a script. The CLI documents `-r, --reverse` as the option that changes the operation to waiting for resources not to be available.

In this example, `NEXT_CMD` runs after port 4000 is no longer available. This is directly applicable to a script that must not continue while a local service is still listening. The README does not document process ownership checks or cleanup of the process that caused the shutdown.

Options can be supplied directly or loaded from a JavaScript or JSON configuration file. Passing `--config configFile.js` causes that file to be required, and the resulting object is merged with command-line options before wait-on runs. The repository includes `exampleConfig.js`, but the README does not show its complete contents, so a full configuration example cannot be reproduced from the available project documentation.

HTTP headers can also be passed repeatedly with `-H` or `--header`. CLI headers override configuration-file headers when their names conflict. This supports authenticated probes, although the README does not describe credential storage, masking of sensitive values in logs, or secret-management integration.

wait-on also exposes a Node.js API. `package.json` identifies `lib/wait-on` as the main entry point and `index.d.ts` as the TypeScript declaration file, confirming that programmatic consumption is part of the published package. The README does not include a complete API invocation, so application developers should consult `index.d.ts` for the declared API rather than infer constructor options from the CLI.

Where wait-on is the wrong readiness tool

The main limitation is that availability and application health are different concepts. An open TCP port proves that something is accepting connections. A 2xx HTTP response proves that the selected path returned a successful status after redirects. Neither statement proves that dependencies are ready, background initialization has finished, or the service can complete a real workload.

wait-on is therefore the wrong tool when readiness requires several assertions inside an application. The documented interface does not verify that a database transaction completed, a queue drained, or a file is semantically valid. A `command:` resource can wrap such a test, but then the quality and exit-code semantics of that test belong to the wrapped command.

Endpoint selection can also make an otherwise working service appear broken. A `HEAD` probe may fail on a server that implements `GET` only. A readiness path that intentionally returns `404` will fail under the default 2XX rule unless `--status-codes` changes it. Widening that range can make the check pass for any client, authentication, or routing error, so the chosen status range must reflect the operational contract.

Infinite waiting is another concrete failure mode. The default global timeout is `Infinity`, so a typo, wrong port, or stopped service can leave an automated process waiting indefinitely unless an external system interrupts it. wait-on is better suited to a dependency condition with a stable, externally observable probe than to an open-ended readiness conversation with a service.

wait-on versus application health scripts and process managers

A real alternative is to put readiness in an application-specific health script and gate on `command:`. This approach can inspect domain state or call a richer validation sequence, while wait-on focuses on resource transport and timing. The tradeoff is that the wrapped script must be maintained and must return meaningful exit codes. wait-on supplies the cross-platform waiting loop, but it does not define what domain health means.

Another approach is to use the shell, an external process manager, or an orchestrator that already models service startup and shutdown. That avoids adding wait-on when the surrounding system already retries and starts processes according to health checks. wait-on is more directly useful in a plain Node.js script, npm workflow, test setup, or shell sequence that needs a compact conditional gate across files, sockets, ports, and HTTP responses.

Its operational footprint is small. The published npm package includes `bin/`, `lib/`, `exampleConfig.js`, and `index.d.ts`, while the runtime dependencies include `axios`, `joi`, `lodash`, and `rxjs`. The repository is not archived, and the last push was on 2026-09-30. Recent releases include `v9.5.1` and `v10.0.0-rc.1`, so the package has recent release activity, although an `rc` release should not be treated as the stable default without checking its intended use.

The MIT license permits use, modification, distribution, and sublicensing under its terms, subject to the license text. That is relevant for packaging and commercial integration, but organizations still need to review dependency licenses and their own distribution obligations separately.

Editorial conclusion

Adopt wait-on when a Node.js process needs a small, cross-platform gate for several local or remote resources. Do not choose it as a substitute for an application health check that validates internal state. Before adoption, verify the exact readiness contract: use HTTP GET when HEAD is misleading, set a finite timeout for unattended scripts, and confirm the success statuses match what the service actually returns.

Frequently asked questions

How do I install wait-on for a Node.js project?

Run `npm install wait-on` for a project-local installation or `npm install -g wait-on` for a global installation. The current package manifest requires Node.js `>=20.0.0`.

How can wait-on wait for a web service without using HEAD?

Use an `http-get:` or `https-get:` resource instead of `http:` or `https:`. These prefixes send a `GET` request, which is useful when the server does not implement `HEAD` or readiness depends on the response body.

What happens if wait-on times out or is interrupted?

It exits with a non-zero exit code. In a shell command joined with `&&`, that prevents the following command from running; the global `--timeout` defaults to `Infinity`, so unattended workflows should normally set a finite limit.

Can wait-on wait for a service to shut down?

Yes. The `--reverse` or `-r` option changes the condition to unavailable resources, allowing a script to continue after a TCP port, socket, file, or HTTP resource no longer satisfies its normal check.

Official sources

  1. Issues
  2. jeffbski/wait-on on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jeffbski-wait-on.svg)](https://hysenlabs.com/projects/jeffbski-wait-on)

Was this useful?