Parallel Works

Endpoint Sessions

An endpoint session exposes an app running on a machine you control — your workstation, a server, a VM, or any host that can reach the platform — through ACTIVATE, without deploying it or opening any inbound ports. The pw CLI dials out and registers a reverse tunnel, so no inbound network access to that machine is required; nothing on it has to accept incoming connections.

A tunnel session exposes an app running on a remote compute resource, where an agent on the cluster initiates the tunnel. An endpoint session is independent of any cluster or agent — the pw CLI dials out on its own, so you can expose an app from any machine you run it on.

Expose a local app

Run pw endpoints http next to an app listening on a port (or a Unix socket):

# Expose a local app on port 3000
pw endpoints http 3000

The CLI prints a public URL (for example https://my-app.<sessions-domain>/) and forwards traffic to your local app until you stop it with Ctrl+C. Use pw endpoints https instead when your local app speaks TLS.

A few common options:

  • --name <name> — give the session a stable name; re-running takes over the same endpoint.
  • --subdomain <label> — choose the subdomain instead of getting a random one.
  • --open — open the URL in your browser once the tunnel is up.
  • --public — let anyone with the link reach the endpoint without logging in (requires your organization to allow public sessions).

See the pw endpoints CLI reference for the full list of commands and flags.

Troubleshooting

Live reload (HMR) doesn't work, or the page never finishes loading

If you tunnel a framework dev server (Next.js, Vite, and similar) and the page loads but never finishes rendering or updating — and the browser console shows repeated WebSocket failures to a Hot Module Reload endpoint such as /_next/webpack-hmr — the dev server is rejecting the connection because it arrives cross-origin.

Requests reach your dev server with the public endpoint host (*.<sessions-domain>) rather than localhost. Dev servers allow only same-origin requests to their Hot Module Reload socket and internal dev routes by default, so they close the connection, which can leave the page stuck before it finishes loading.

This is a dev-server setting, not a tunnel limitation — endpoint sessions forward WebSockets normally. Allow the endpoint host in your dev server's config:

  • Next.js — add the host to allowedDevOrigins in next.config.js:

    module.exports = {
      allowedDevOrigins: ['my-app.<sessions-domain>'],
    }
  • Vite — add the host to server.allowedHosts in vite.config.js.

Restart the dev server after changing its config.

Production builds are unaffected: they have no Hot Module Reload socket, so they work through an endpoint session with no extra configuration.