These days it’s pretty common for a system to consist of multiple separate applications – whether it’s microservices, Self-Contained Systems or something else entirely. Thus for development purposes, it might be necessary to spin up more than one application at a time (though hopefully not too many).

I’ve found it helpful to distinguish between a primary application, i.e. whatever I’m currently focusing on, and auxiliary systems, e.g. an asset server for static CSS and JavaScript files. While both of those have to work in tandem, I might not care about the particular details of auxiliary systems: Whoever is responsible for such a system just needs to provide simple instructions on how to start the respective process and have it listen on a given port. (Docker can be very helpful in that regard.)

For web applications, it’s often necessary that collaborating systems be accessed via the same host (or origin), so having individual applications running on separate ports may be a problem – which can be remedied with a reverse proxy:

reverse proxy
reverse proxy mediating access to two separate applications

I’m assuming here that our applications are served on separate paths rather than, say, subdomains.

While conceptually straightforward, setting up a reverse proxy can be a bit of a pain. Apache and nginx are excellent for production systems, but typically overkill for local development and not trivial to configure.

Since modern web applications typically rely on Node.js tooling for front-end concerns, express-http-proxy seems like an obvious alternative. However, with its host of options, it can be a little intimidating as well – which is why I wrote a small wrapper providing a simplified, declarative way to set up a reverse proxy for local development:

module.exports = {
    "/app": {
        uri: "localhost:8081",
        preserveHost: true,
        preservePrefix: true
    "/assets": "localhost:8082"

After installing dprox via npm, dprox will launch a reverse proxy listening at localhost:3333. Now we just have to start our applications and make sure they’re listening on the ports we’ve configured here.