npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

udpsplitr

v0.1.0

Published

UDP proxy that splits client and server traffic across separate ports

Readme

UDPSplitR

UDPSplitR is a UDP proxy that splits outgoing and incoming traffic across different ports. The client sends proxied packets from one local port and listens for server responses on another, while the server receives client packets and forwards them to TARGET_IP:TARGET_PORT.


The tool is useful when a UDP flow needs separate paths for input and output traffic between the client-side proxy and the server-side proxy.

The client side intentionally supports one active local UDP peer at a time. The first peer that sends traffic owns the return path; packets from other peers are rejected so responses are not accidentally delivered to the wrong process.

For deployments behind NAT, the experimental NAT_TRAVERSAL option can make the client response socket send keepalive packets. This lets the server learn the observed return endpoint instead of relying only on the configured CLIENT_RESPONSE_IP and CLIENT_RESPONSE_PORT.

Traffic Schema

                 outgoing path
┌───────────────┐   CLIENT_PROXY_PORT   ┌───────────────────┐   SERVER_PORT   ┌───────────────────┐   TARGET_PORT   ┌──────────────┐
│ Local UDP app │ ────────────────────> │ UDPSplitR client  │ ──────────────> │ UDPSplitR server  │ ──────────────> │ Target UDP   │
└───────────────┘                       └───────────────────┘                 └───────────────────┘                 └──────────────┘
        ▲                                      │                                  │                                │
        │                                      │                                  │                                │
        └──────────────────────────────────────┘ <────────────────────────────────┘ <──────────────────────────────┘
              CLIENT_RESPONSE_PORT                         response path

The important part is that the client-side proxy uses different ports for the two directions: CLIENT_PROXY_PORT for incoming local traffic and CLIENT_RESPONSE_PORT for responses from the server.

In --ping-mode, the client prepends a probe ID to each echo payload and matches responses by that ID. The console output is formatted like standard ping, with a PING ... banner, 1-second probe intervals, and per-probe latency lines.

Configuration

Both the client and server proxies have the following configuration options, which can be set in a .env file:

  • CLIENT_IP: The IP address to listen for client connections (default: 0.0.0.0).
  • CLIENT_PROXY_PORT: The port to listen for client connections (default: 27817).
  • CLIENT_RESPONSE_PORT: The port to receive responses from the server (default: 27818).
  • SERVER_IP: The IP address of the server to forward data to.
  • SERVER_PORT: The port to forward data to the server (default: 27817).
  • TARGET_IP: The IP address of the target server to forward data to.
  • TARGET_PORT: The port to forward data to the target server (default: 443).
  • CLIENT_RESPONSE_IP: The IP address of the client to receive responses.
  • CLIENT_RESPONSE_PORT: The port to receive responses from the target server (default: 27818).
  • MTU_SIZE: The Maximum Transmission Unit size (default: 1450).
  • NAT_TRAVERSAL: Enables client response-port keepalives so the server learns the NAT-mapped return path for responses (default: false).

NAT_TRAVERSAL is an experimental feature. It relies on periodic client keepalives to keep the response-port mapping alive through NAT and firewalls, and behavior will vary by network.

When NAT_TRAVERSAL is enabled, the client response socket periodically sends a small keepalive packet to the server. The server uses the observed source address and port as the return path for responses instead of the static CLIENT_RESPONSE_IP and CLIENT_RESPONSE_PORT values.

Usage

Run With npx

Run the proxy directly from npm without installing it globally.

Generate configuration:

Server Machine

npx udpsplitr server --init-env

Client Machine

npx udpsplitr client --init-env

The command copies the packaged env.example file and sets MODE for the selected role. It will not overwrite an existing .env unless --force is passed.

Run the proxy:

Server Machine

npx udpsplitr server

Client Machine

npx udpsplitr client

Install Globally

Install the command once and run it as udpsplitr:

npm install -g udpsplitr

Generate configuration:

Server Machine

udpsplitr server --init-env

Client Machine

udpsplitr client --init-env

Run the proxy:

Server Machine

udpsplitr server

Client Machine

udpsplitr client

Docker

Create Configuration

Use a temporary container to generate a local .env file before running Docker examples.

Server Machine

docker run --rm -v "$PWD:/config" -w /config ghcr.io/jstarstech/udpsplitr:latest node app.js server --init-env

Client Machine

docker run --rm -v "$PWD:/config" -w /config ghcr.io/jstarstech/udpsplitr:latest node app.js client --init-env

Temporary Echo/Ping

Server Machine

docker run -d --rm --env-file .env --name udpsplitr-server ghcr.io/jstarstech/udpsplitr:latest node app.js server --echo-mode

Client Machine

docker run -d --rm --env-file .env --name udpsplitr-client ghcr.io/jstarstech/udpsplitr:latest node app.js client --ping-mode

Development

Clone Repository

git clone https://github.com/jstarstech/udpsplitr.git
cd udpsplitr
npm install

Local Configuration

Server Machine

node app.js server --init-env

Client Machine

node app.js client --init-env

Local Run

Server Machine

node app.js server

Client Machine

node app.js client

Checks And Tests

npm run check
npm test

Docker Compose

Copy env.example to .env on each machine:

cp env.example .env

Set the mode in .env to match the machine role:

# server machine
MODE=server

# client machine
MODE=client

Run Compose normally on both machines:

docker compose up --build