# udx-native

> udx is reliable, multiplexed, and congestion-controlled streams over udp

Latest version **1.21.1** (published 2026-08-20) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install udx-native
pnpm add udx-native
yarn add udx-native
bun add udx-native
```

## Health

**Score 60/100 (C)** — status: active.

Positive: no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types; no esm support.

## Facts

| | |
|---|---|
| Version | 1.21.1 |
| Published | 2026-08-20 |
| First published | 2022-01-27 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 4 |
| Unpacked size | 4.8 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 28 |
| Author | Holepunch Inc. |
| Maintainers | mafintosh |
| Keywords | tcp, udp, stream, reliable |

## Links

- npm: https://www.npmjs.com/package/udx-native
- Repository: https://github.com/holepunchto/udx-native
- Homepage: https://github.com/holepunchto/udx-native#readme
- Issues: https://github.com/holepunchto/udx-native/issues
- npm.io page: https://npm.io/package/udx-native

## Dependencies (4)

- [b4a](https://npm.io/package/b4a.md) ^1.5.0
- [streamx](https://npm.io/package/streamx.md) ^2.22.0
- [bare-events](https://npm.io/package/bare-events.md) ^2.2.0
- [require-addon](https://npm.io/package/require-addon.md) ^1.1.0

## Alternatives

- [byte-size](https://npm.io/package/byte-size.md) — 2.1M weekly downloads
- [speed-limiter](https://npm.io/package/speed-limiter.md) — 16.0K weekly downloads
- [@powersync/node](https://npm.io/package/@powersync/node.md) — 10.9K weekly downloads
- [@ledgerhq/coin-cardano](https://npm.io/package/@ledgerhq/coin-cardano.md) — 1.0K weekly downloads
- [@jayesol/jayeson.lib.streamfinder](https://npm.io/package/@jayesol/jayeson.lib.streamfinder.md) — 1.0K weekly downloads

## Recent versions

- 1.21.1 (latest) — 2026-08-20
- 1.20.6 (next) — 2026-05-19
- 1.21.2 — 2026-09-08
- 1.21.0 — 2026-08-05
- 1.20.7 — 2026-06-11
- 1.20.5 — 2026-05-01
- 1.20.4 — 2026-04-10
- 1.20.3 — 2026-03-25
- 1.20.2 — 2026-03-05
- 1.20.1 — 2026-02-25
- 1.20.0 — 2026-02-12
- 1.19.2 — 2025-10-15
- 1.19.1 — 2025-10-02
- 1.19.0 — 2025-08-25
- 1.18.3 — 2025-08-21
- … 108 more at https://npm.io/package/udx-native/versions

## README

# udx-native

udx is reliable, multiplexed, and congestion-controlled streams over udp.

```
npm i udx-native
```

It's a transport protocol, made only for peer-to-peer networking.

No handshakes. No encryption. No features. This is good for P2P.\
Just fast streams and messages that are composable into powerful things.

## Usage

```js
const UDX = require('udx-native')

const u = new UDX()
const a = u.createSocket()
const b = u.createSocket()

b.on('message', function (message) {
  console.log('received', message.toString())
  a.close()
  b.close()
})

b.bind(0)
a.send(Buffer.from('hello'), b.address().port)
```

```js
const UDX = require('udx-native')

const u = new UDX()

const socket1 = u.createSocket()
const socket2 = u.createSocket()

socket1.bind()
socket2.bind()

const stream1 = u.createStream(1)
const stream2 = u.createStream(2)

stream1.connect(socket1, stream2.id, socket2.address().port, '127.0.0.1')
stream2.connect(socket2, stream1.id, socket1.address().port, '127.0.0.1')

stream1.write(Buffer.from('hello'))
stream1.end()

stream2.on('data', function (data) {
  console.log(data)
})

stream2.on('end', function () {
  stream2.end()
})

stream1.on('close', function () {
  console.log('stream1 closed')
  socket1.close()
})

stream2.on('close', function () {
  console.log('stream2 closed')
  socket2.close()
})
```

## API

#### `const udx = new UDX()`

Creates a new UDX instance.

#### `const bool = UDX.isIPv4(host)`

Returns `true` if host is an IPv4 address.

#### `const bool = UDX.isIPv6(host)`

Returns `true` if host is an IPv6 address.

#### `const family = UDX.isIP(host)`

Returns the address family (`4` or `6`). Returns `0` if invalid.

## Sockets

#### `const socket = udx.createSocket([options])`

Creates a new socket instance.

Available `options`:

```js
{
  ipv6Only: false,
  reuseAddress: false
}
```

#### `socket.udx`

It's the UDX instance from where the socket was created.

#### `socket.streams`

It's a `Set` that tracks active streams (connected to the socket but not closed).

#### `socket.userData`

Optional custom userData. Default is `null`.

#### `socket.bound`

Indicates if it's bound to any port. It will be `true` after a successful `bind()`.

#### `socket.closing`

It will be `true` after `close()` is called.

#### `socket.idle`

Indicates that the socket doesn't have any connected stream.

#### `socket.busy`

Indicates that the socket have at least one connected stream.

#### `socket.address()`

Returns an object like `{ host, family, port }`. Only available after `bind()`.

#### `socket.bind([port], [host])`

The default port is `0`.\
If no host specified: it binds to IPv6 `::`. If fails then IPv4 `0.0.0.0`.

#### `await socket.close()`

It unbinds the socket so it stops listening for messages.

#### `socket.setTTL(ttl)`

Sets the amount of times that a packet is allowed to be forwarded through each router or gateway before being discarded.

#### `socket.getRecvBufferSize()`

#### `socket.setRecvBufferSize()`

#### `socket.getSendBufferSize()`

#### `socket.setSendBufferSize()`

#### `await socket.send(buffer, port, [host], [ttl])`

Sends a message to port and host destination. Default host is `127.0.0.1`.

#### `socket.trySend(buffer, port, [host], [ttl])`

Same behaviour as `send()` but no promise.

#### `socket.on('message', (msg, from) => {})`

`msg` is a buffer that containts the message.\
`from` is an object like `{ host, family, port }`.

#### `socket.on('close', onclose)`

Emitted if the socket was ever bound and it got closed.

#### `socket.on('idle', onidle)`

Emitted if the socket becomes idle (no active streams).

#### `socket.on('busy', onbusy)`

Emitted if the socket becomes busy (at least one active stream).

#### `socket.on('listening', onlistening)`

Emitted after a succesfull `bind()` call.

## Streams

#### `const stream = udx.createStream(id, [options])`

Creates a new stream instance that is a Duplex stream.

Available `options`:

```js
{
  firewall: (socket, port, host) => true,
  framed: false,
  seq: 0
}
```

#### `stream.udx`

It's the UDX instance from where the stream was created.

#### `stream.socket`

Refers to the socket that is connected to. Setted when you `connect()` the stream.

#### `stream.id`

Custom stream id.

#### `stream.remoteId`

Remote stream id. Setted when you `connect()` the stream.

#### `stream.remoteId`

Remote stream id. Setted when you `connect()` the stream.

#### `stream.remoteHost`

Remote host. Setted when you `connect()` the stream.

#### `stream.remoteFamily`

Remote family (`4` or `6`). Setted when you `connect()` the stream.

#### `stream.remotePort`

Remote port. Setted when you `connect()` the stream.

#### `stream.userData`

Optional custom userData. Default is `null`.

#### `stream.connected`

Indicates if the stream is connected to a socket. It becomes `false` if the stream is closed.

#### `stream.mtu`

Indicates the maximum size of each packet.

#### `stream.rtt`

#### `stream.cwnd`

#### `stream.inflight`

#### `stream.localHost`

Indicates the connected socket host address. By default `null` if not connected.

#### `stream.localFamily`

Indicates the connected socket family address (`4` o `6`). By default `0` if not connected.

#### `stream.localPort`

Indicates the connected socket port. By default `0` if not connected.

#### `stream.setInteractive(bool)`

#### `stream.connect(socket, remoteId, port, [host], [options])`

Connects the stream using a socket to a: remote stream id, and remote socket port/host.

If no host specified it uses `127.0.0.1` by default.

Available `options`:

```js
{
  ack
}
```

#### `await stream.changeRemote(remoteId, port, [host])`

Change the remote end of the stream.

If no host specified it uses `127.0.0.1` by default.

#### `stream.relayTo(destination)`

Relay stream to another stream.

#### `await stream.send(buffer)`

Send a message to another stream. Returns a promise.

#### `stream.trySend(buffer)`

Send a message to another stream.

#### `const drained = await stream.flush()`

Wait for pending stream writes to have been explicitly acknowledged by the other side of the connection.

#### `stream.on('connect', onconnect)`

Emitted after the stream is connected to a socket.

#### `stream.on('message', onmessage)`

Emitted if the stream receives a message.

#### `stream.on('remote-changed', onremotechanged)`

Emitted when the remote end of the stream changes.

#### `stream.on('mtu-exceeded', onmtuexceeded)`

Emitted only once if you write data that exceeds the MTU.

## Network interfaces

#### `const interfaces = udx.networkInterfaces()`

Returns an array of network interfaces, for example:

```js
;[
  { name: 'lo', host: '127.0.0.1', family: 4, internal: true },
  { name: 'enp4s0', host: '192.168.0.20', family: 4, internal: false },
  { name: 'lo', host: '::1', family: 6, internal: true },
  {
    name: 'enp4s0',
    host: 'df08::c8df:bf61:95c1:352b',
    family: 6,
    internal: false
  }
]
```

#### `const watcher = udx.watchNetworkInterfaces([onchange])`

Listens to changes in the network interfaces. The `watcher` object is iterable.

#### `watcher.interfaces`

Array of network interfaces.

#### `watcher.watch()`

Starts watching for changes. By default it already does it. This is only useful after you `unwatch()`.

#### `watcher.unwatch()`

Stops watching for changes.

#### `await watcher.destroy()`

Closes the watcher.

#### `watcher.on('change', onchange)`

Emitted after a network interface change.

#### `watcher.on('close', onclose)`

Emitted after the watcher is closed.

## DNS

#### `const address = await udx.lookup(host, [options])`

It does a DNS lookup for the IP address. Returns `{ host, family }`.

Available `options`:

```js
{
  family: 0 // => 0, 4 or 6
}
```

## Dev Setup

To develop UDX locally, you need to create a libudx prebuild. [bare-make](https://github.com/holepunchto/bare-make) is used for this.

Requirements: The Clang C-compiler should be installed.

The other setup steps are:

- `npm install -g bare-runtime bare-make`
- `npm install`
- `bare-make generate`
- `bare-make build`
- `bare-make install`

When testing changes, rebuild the prebuilds:

- `bare-make generate`
- `bare-make build`
- `bare-make install`

## License

Apache-2.0

---
_Source: https://npm.io/package/udx-native · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
