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

@devioarts/capacitor-tcpclient

v0.2.1

Published

TCP Client for Capacitor working on Android, iOS and Electron

Readme

@devioarts/capacitor-tcpclient

TCP client plugin for Capacitor apps with native Android, iOS and Electron support.

Use it when your app needs to talk to a TCP device or service directly, for example printers, scanners, controllers, gateways or local network hardware.

Features

  • Native TCP sockets on Android, iOS and Electron
  • Multi-connection API with isolated listeners per connection
  • Raw writes, continuous stream reads and request/response reads
  • Byte payloads as number[] or Uint8Array
  • Optional expect pattern matching for protocol replies
  • Web stub for browser development builds

Install

npm install @devioarts/capacitor-tcpclient
npx cap sync

Android network permissions are merged automatically from the plugin manifest. See Getting started for manual Android fallback notes and the required iOS setup.

Quick Start

import { TCPClient } from '@devioarts/capacitor-tcpclient';

const conn = TCPClient.createConnection({
  host: '192.168.1.100',
  port: 9100,
  timeout: 3000,
});

await conn.connect();

const reply = await conn.writeAndRead({
  data: [0x1b, 0x40],
  timeout: 1000,
  maxBytes: 4096,
});

if (reply.error) {
  console.error(reply.errorMessage);
} else {
  console.log('Received bytes:', reply.data);
}

await conn.destroy();

Capacitor App Example

import { TCPClient, type TCPConnection } from '@devioarts/capacitor-tcpclient';

let connection: TCPConnection | undefined;

export async function connectToDevice(host: string) {
  connection = TCPClient.createConnection({ connectionId: 'main-device', host, port: 9100 });

  await connection.addListener('tcpDisconnect', ({ reason, error }) => {
    console.log('TCP disconnected:', reason, error ?? '');
  });

  return connection.connect();
}

export async function sendCommand(command: Uint8Array) {
  if (!connection) throw new Error('TCP connection is not ready');

  return connection.writeAndRead({
    data: command,
    expect: '0d0a',
    timeout: 1500,
    maxBytes: 8192,
  });
}

export async function disconnectFromDevice() {
  await connection?.destroy();
  connection = undefined;
}

Documentation

Platform Support

| Platform | Status | Notes | | --- | --- | --- | | Android | Native TCP | Internet/network permissions are merged automatically | | iOS | Native TCP | Requires local network usage description for local devices | | Electron | Native TCP | Use Capacitor Electron or the manual bridge | | Web | Development stub | Keeps the same API shape, but does not open real TCP sockets |

Common Commands

npm run build
npm test
npm run verify:web

API

The generated API below documents the root @devioarts/capacitor-tcpclient entry point used by Capacitor apps. The manual Electron bridge exposes the native methods directly over IPC, so it uses connectionId on every call instead of createConnection().

createConnection(...)

createConnection(options?: TcpCreateConnectionOptions | undefined) => TCPConnection

Create (or retrieve) a TCP connection instance.

  • Without connectionId: always creates a new instance with a generated UUID.
  • With connectionId: returns the existing instance if one was already created, otherwise creates a new one.
  • host/port/timeout/noDelay/keepAlive supplied here become defaults for connect().

| Param | Type | | ------------- | --------------------------------------------------------------------------------- | | options | TcpCreateConnectionOptions |

Returns: TCPConnection


getPluginPlatform()

getPluginPlatform() => Promise<TcpGetPlatformResult>

Returns the platform identifier for this plugin's native implementation ('ios' | 'android' | 'electron' | 'web').

Distinct from the Capacitor core Capacitor.getPlatform() — use this when you need to know whether the TCP layer is backed by iOS, Android, Electron, or the browser development stub.

Returns: Promise<TcpGetPlatformResult>


Interfaces

TCPConnection

A single TCP connection instance returned by TCPClient.createConnection(). Each instance has its own socket, event listeners, and lifecycle.

| Prop | Type | | ------------------ | ------------------- | | connectionId | string |

| Method | Signature | Description | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | connect | (options?: Partial<TcpConnectOptions> | undefined) => Promise<TcpConnectResult> | Open the socket. Options are merged with the defaults supplied in createConnection(). host must be present either in createConnection() or here. | | disconnect | () => Promise<TcpDisconnectResult> | Close the socket. Idempotent. Resolves after native teardown completes. Emits tcpDisconnect(reason: manual). | | isConnected | () => Promise<TcpIsConnectedResult> | | | isReading | () => Promise<TcpIsReadingResult> | | | write | (options: TcpWriteOptions) => Promise<TcpWriteResult> | | | writeAndRead | (options: TcpWriteAndReadOptions) => Promise<TcpWriteAndReadResult> | | | startRead | (options?: TcpStartReadOptions | undefined) => Promise<TcpStartStopResult> | | | stopRead | () => Promise<TcpStartStopResult> | | | setReadTimeout | (options: { readTimeout: number; }) => Promise<{ error: boolean; errorMessage?: string | null; }> | Configure stream read timeout. - Android: sets SO_TIMEOUT on the continuous reader socket (applies during startRead). - iOS: no-op (evented I/O, no blocking timeout). - Electron: sets the default timeout value used by writeAndRead when no explicit timeout is passed; if called before connect, the default is stored without creating a socket state entry. | | addListener | (eventName: 'tcpData', listenerFunc: (event: TcpDataEvent) => void) => Promise<PluginListenerHandle> | Subscribe to stream data. Only events for this connectionId are delivered. | | addListener | (eventName: 'tcpDisconnect', listenerFunc: (event: TcpDisconnectEvent) => void) => Promise<PluginListenerHandle> | Subscribe to disconnect notifications for this connection. | | removeAllListeners | () => Promise<void> | Remove all listeners registered through this instance. | | destroy | () => Promise<void> | Disconnect, remove all listeners, and release this instance from the registry even if listener cleanup fails. |

TcpConnectResult

| Prop | Type | | ------------------ | --------------------------- | | error | boolean | | errorMessage | string | null | | connected | boolean |

TcpConnectOptions

| Prop | Type | Description | | --------------- | -------------------- | -------------------------------------------------------------------------------------- | | host | string | Hostname or IP address. Required (either here or in createConnection). | | port | number | TCP port, default 9100. Valid range 1..65535. | | timeout | number | Connect timeout in milliseconds, default 3000. Includes DNS and socket connect budget. | | noDelay | boolean | Enable TCP_NODELAY (Nagle off). Default true. | | keepAlive | boolean | Enable SO_KEEPALIVE. Default true. |

TcpDisconnectResult

| Prop | Type | | ------------------ | --------------------------- | | error | boolean | | errorMessage | string | null | | disconnected | boolean | | reading | boolean |

TcpIsConnectedResult

| Prop | Type | | ------------------ | --------------------------- | | error | boolean | | errorMessage | string | null | | connected | boolean |

TcpIsReadingResult

| Prop | Type | | ------------------ | --------------------------- | | error | boolean | | errorMessage | string | null | | reading | boolean |

TcpWriteResult

| Prop | Type | | ------------------ | --------------------------- | | error | boolean | | errorMessage | string | null | | bytesSent | number |

TcpWriteOptions

| Prop | Type | | ---------- | --------------------------------------------------------- | | data | TcpBytePayload |

TcpByteArrayLike

Byte-like array accepted by write APIs. Uint8Array is supported because it has numeric indexes and a length.

| Prop | Type | | ------------ | ------------------- | | length | number |

TcpWriteAndReadResult

| Prop | Type | | ------------------- | --------------------------- | | error | boolean | | errorMessage | string | null | | bytesSent | number | | bytesReceived | number | | data | number[] | | matched | boolean |

TcpWriteAndReadOptions

| Prop | Type | Description | | --------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | data | TcpBytePayload | | | timeout | number | RR timeout in ms. Default 1000. Values <= 0 fall back to the default. | | maxBytes | number | Maximum bytes to accumulate. Default 4096, capped at 16 MiB. | | expect | string | TcpBytePayload | Optional pattern — reading stops when found. Accepts number[] / Uint8Array or hex string (e.g. "1B40", "0x1b 0x40"). Empty values are treated as no expect pattern. | | suspendStreamDuringRR | boolean | Suspend stream reader during RR to avoid consuming reply. Default true. |

TcpStartStopResult

| Prop | Type | | ------------------ | --------------------------- | | error | boolean | | errorMessage | string | null | | reading | boolean |

TcpStartReadOptions

| Prop | Type | Description | | ----------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | chunkSize | number | Stream read chunk size in bytes. Default 4096, capped at 16 MiB. - Android/iOS: size of each native socket read before bridge micro-batching. - Electron: maximum bytes per emitted tcpData event after micro-batching. | | readTimeout | number | Stream read timeout in ms. - Android: sets SO_TIMEOUT for the continuous reader. - iOS: no-op. - Electron: updates the per-connection default writeAndRead timeout; the stream reader itself remains event-driven. |

PluginListenerHandle

| Prop | Type | | ------------ | ----------------------------------------- | | remove | () => Promise<void> |

TcpDataEvent

Emitted by the stream reader. connectionId identifies which connection sent the data.

| Prop | Type | | ------------------ | --------------------- | | connectionId | string | | data | number[] |

TcpDisconnectEvent

Emitted when a connection closes.

| Prop | Type | | ------------------ | -------------------------------------------- | | connectionId | string | | disconnected | true | | reading | boolean | | reason | 'error' | 'manual' | 'remote' | | error | string |

TcpCreateConnectionOptions

Options for TCPClient.createConnection(). All fields are optional. host/port and other connect options set here become defaults for every connect() call on the returned instance.

| Prop | Type | Description | | ------------------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | connectionId | string | Optional stable identifier for this connection. If an instance with this id already exists in the registry, it is returned as-is. Omit to get a new instance with a generated UUID each time. |

TcpGetPlatformResult

| Prop | Type | | ------------------ | --------------------------------------------------- | | error | boolean | | errorMessage | string | null | | platform | TcpPlatform |

Type Aliases

Partial

Make all properties in T optional

{ [P in keyof T]?: T[P]; }

TcpBytePayload

Byte payload accepted by write APIs. Values must be integer bytes in the 0..255 range.

number[] | TcpByteArrayLike

TcpPlatform

'ios' | 'android' | 'web' | 'electron'

License

MIT