Migrating from 0.8

H2O Wave v0.9.0+ introduces significant improvements to application performance and concurrency, and brings us closer to a v1.0 release. v1.0 will include the ability to increase the number of worker processes to scale apps, while preserving the simplicity of the Wave API.

Among other changes, the Wave server executable wave is now called waved (or waved.exe), and the h2o-wave Python package ships with a new CLI named wave.

ASGI Compatibility

Wave apps are now ASGI-compatible, based on the high-performance Uvicorn / Starlette duo.

You can run Wave apps behind any ASGI server, like uvicorn, gunicorn, daphne, hypercorn, etc.

Old way

In versions <= v0.8.0, a skeleton app looked like this:

from h2o_wave import listen, Q
async def serve(q: Q):
listen('/demo', serve)

The above app could be run like this:

(venv) $ python foo.py

New way

In versions v0.9.0+, a skeleton app looks like this:

from h2o_wave import main, app, Q
async def serve(q: Q):


  1. listen(route) has been replaced by an @app(route) decorator on the serve() function.
  2. main needs to be imported into the file (but you don't have to do anything with the symbol main other than simply import it).

The above app can be run using wave run, built into the new wave command line interface.

(venv) $ wave run foo

The wave run command runs your app using live-reload, which means you can view your changes live as you code, without having to refresh your browser manually.

To run your app without live-reload, simply pass --no-reload:

(venv) $ wave run --no-reload foo

To run your app using an ASGI server like uvicorn, append :main to the app argument:

(venv) $ uvicorn foo:main