I think I’m trying to understand how the parts interact. It is my understanding that JupyterHub configures the proxy to forward requests to the appropriate single user notebook server. However, why does the single user notebook server need JupyterHub installed? The reason I ask is that the JupyterHub process is already running prior to spawning the single user notebook servers.
The JupyterHub package includes a JupyterHub singleuser component that wraps the standard jupyter-server/lab/notebook so that it can handle communication with JupyterHub. In theory it could be split into two separate packages, but for convenience both components are bundled into one.