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.0.3

Published

TCP Client for Capacitor working on Android, iOS and Electron

Readme

@devioarts/capacitor-tcpclient

TCP Client for Capacitor with iOS/Android/Electron support - Example App

Install

npm install @devioarts/capacitor-tcpclient
npx cap sync

Android

/android/app/src/main/AndroidManifest.xml

<application 
        android:usesCleartextTraffic="true"
></application>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Android 12+ -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

iOS

/ios/App/App/Info.plist

<key>NSLocalNetworkUsageDescription</key>
<string>It is needed for the correct functioning of the application</string>
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsLocalNetworking</key>
  <true/>
</dict>

ElectronJS

Implementation example was developed on capacitor-electron base, if you run electron differently, you may need to adjust the code.

/electron/main.ts

// ...
// THIS LINE IS IMPORTANT FOR PLUGIN!
import {TCPClient} from "@devioarts/capacitor-tcpclient/electron/tcpclient";
// ...
// THIS LINE IS IMPORTANT FOR PLUGIN!
let tcpClient: TCPClient | null = null;
// ...
function createWindow() {
  const win = new BrowserWindow(
    // ...
  );
  // ...
  // THIS LINE IS IMPORTANT FOR PLUGIN!
  tcpClient = new TCPClient(win);
  // ...
}
// ...

electron/preload.cjs

const { contextBridge, ipcRenderer } = require("electron");

// THIS LINE IS IMPORTANT FOR PLUGIN!
const {createTCPClientAPI} = require("@devioarts/capacitor-tcpclient/electron/tcpclient-bridge.cjs");
// ...
// THIS LINE IS IMPORTANT FOR PLUGIN!
contextBridge.exposeInMainWorld('TCPClient', createTCPClientAPI({ ipcRenderer }));
// ...

API

connect(...)

connect(options: TcpConnectOptions) => Promise<TcpConnectResult>

Open a TCP connection.

| Param | Type | | ------------- | --------------------------------------------------------------- | | options | TcpConnectOptions |

Returns: Promise<TcpConnectResult>


disconnect()

disconnect() => Promise<TcpDisconnectResult>

Close the TCP connection. Idempotent. Triggers tcpDisconnect(manual).

Returns: Promise<TcpDisconnectResult>


isConnected()

isConnected() => Promise<TcpIsConnectedResult>

Check whether the socket is connected.

Returns: Promise<TcpIsConnectedResult>


isReading()

isReading() => Promise<TcpIsReadingResult>

Check whether the stream reader is active.

Returns: Promise<TcpIsReadingResult>


write(...)

write(options: TcpWriteOptions) => Promise<TcpWriteResult>

Write raw bytes.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | TcpWriteOptions |

Returns: Promise<TcpWriteResult>


writeAndRead(...)

writeAndRead(options: TcpWriteAndReadOptions) => Promise<TcpWriteAndReadResult>

Write request, then read reply under the given constraints.

| Param | Type | | ------------- | ------------------------------------------------------------------------- | | options | TcpWriteAndReadOptions |

Returns: Promise<TcpWriteAndReadResult>


startRead(...)

startRead(options?: TcpStartReadOptions | undefined) => Promise<TcpStartStopResult>

Start emitting tcpData events. Safe to call multiple times.

| Param | Type | | ------------- | ------------------------------------------------------------------- | | options | TcpStartReadOptions |

Returns: Promise<TcpStartStopResult>


stopRead()

stopRead() => Promise<TcpStartStopResult>

Stop emitting tcpData events. Safe to call multiple times.

Returns: Promise<TcpStartStopResult>


setReadTimeout(...)

setReadTimeout(options: { readTimeout: number; }) => Promise<{ error: boolean; errorMessage?: string | null; }>

Configure stream read timeout (Android only). iOS: no-op; Electron: stored for RR defaults. Provided for API parity across platforms.

| Param | Type | | ------------- | ------------------------------------- | | options | { readTimeout: number; } |

Returns: Promise<{ error: boolean; errorMessage?: string | null; }>


addListener('tcpData', ...)

addListener(eventName: 'tcpData', listenerFunc: (event: TcpDataEvent) => void) => Promise<PluginListenerHandle>

Subscribe to micro-batched stream data events.

| Param | Type | | ------------------ | ------------------------------------------------------------------------- | | eventName | 'tcpData' | | listenerFunc | (event: TcpDataEvent) => void |

Returns: Promise<PluginListenerHandle>


addListener('tcpDisconnect', ...)

addListener(eventName: 'tcpDisconnect', listenerFunc: (event: TcpDisconnectEvent) => void) => Promise<PluginListenerHandle>

Subscribe to disconnect notifications.

| Param | Type | | ------------------ | ------------------------------------------------------------------------------------- | | eventName | 'tcpDisconnect' | | listenerFunc | (event: TcpDisconnectEvent) => void |

Returns: Promise<PluginListenerHandle>


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all tcpData/tcpDisconnect listeners.


Interfaces

TcpConnectResult

Result of connect().

  • connected=true on success; false on failure.
  • error=true with errorMessage on failure (e.g., "connect timeout", "connect failed: ...").

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

TcpConnectOptions

Connection parameters for opening a TCP socket.

Notes by platform:

  • Android: validates port range (1..65535); applies TCP_NODELAY and SO_KEEPALIVE according to the flags. Connect timeout is enforced by Socket#connect.
  • iOS: sets TCP_NODELAY, SO_KEEPALIVE and SO_NOSIGPIPE. Connect timeout is enforced using non-blocking connect + polling.
  • Electron: sets noDelay and keepAlive (with 60s initial delay). Connect timeout is emulated via a JS timer that destroys the socket if elapsed.

| Prop | Type | Description | | --------------- | -------------------- | ------------------------------------------------------------------------ | | host | string | Hostname or IP address to connect to. Required. | | port | number | TCP port, defaults to 9100. Valid range 1..65535 (validated on Android). | | timeout | number | Connect timeout in milliseconds, defaults to 3000. | | noDelay | boolean | Enable TCP_NODELAY (Nagle off). Defaults to true. | | keepAlive | boolean | Enable SO_KEEPALIVE. Defaults to true. |

TcpDisconnectResult

Result of disconnect(). Always resolves. After disconnect, reading is false. A tcpDisconnect event with reason 'manual' is also emitted by platforms.

| Prop | Type | Description | | ------------------ | --------------------------- | -------------------------------------------------------------------- | | error | boolean | | | errorMessage | string | null | | | disconnected | boolean | True if the instance transitioned to disconnected state. | | reading | boolean | Whether the stream reader is active (always false after disconnect). |

TcpIsConnectedResult

Result of isConnected().

  • Android performs a safe 1-byte peek unless streaming/RR is active, in which case it returns true if those are active to avoid consuming input.
  • iOS/Electron return based on current socket open/close state.

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

TcpIsReadingResult

Result of isReading(). True if stream reader is active.

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

TcpWriteResult

Result of write().

  • bytesSent equals the request length on success; 0 on failure.
  • Fails with error=true if not connected or busy (RR in progress on some platforms).

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

TcpWriteOptions

Bytes to write to the socket verbatim. Accepts number[] or Uint8Array.

| Prop | Type | | ---------- | ------------------------------------------------------------- | | data | number[] | Uint8Array |

Uint8Array

A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.

| Prop | Type | Description | | ----------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------- | | BYTES_PER_ELEMENT | number | The size in bytes of each element in the array. | | buffer | ArrayBufferLike | The ArrayBuffer instance referenced by the array. | | byteLength | number | The length in bytes of the array. | | byteOffset | number | The offset in bytes of the array. | | length | number | The length of the array. |

| Method | Signature | Description | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | copyWithin | (target: number, start: number, end?: number | undefined) => this | Returns the this object after copying a section of the array identified by start and end to the same array starting at position target | | every | (predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any) => boolean | Determines whether all the members of an array satisfy the specified test. | | fill | (value: number, start?: number | undefined, end?: number | undefined) => this | Returns the this object after filling the section identified by start and end with value | | filter | (predicate: (value: number, index: number, array: Uint8Array) => any, thisArg?: any) => Uint8Array | Returns the elements of an array that meet the condition specified in a callback function. | | find | (predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any) => number | undefined | Returns the value of the first element in the array where predicate is true, and undefined otherwise. | | findIndex | (predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any) => number | Returns the index of the first element in the array where predicate is true, and -1 otherwise. | | forEach | (callbackfn: (value: number, index: number, array: Uint8Array) => void, thisArg?: any) => void | Performs the specified action for each element in an array. | | indexOf | (searchElement: number, fromIndex?: number | undefined) => number | Returns the index of the first occurrence of a value in an array. | | join | (separator?: string | undefined) => string | Adds all the elements of an array separated by the specified separator string. | | lastIndexOf | (searchElement: number, fromIndex?: number | undefined) => number | Returns the index of the last occurrence of a value in an array. | | map | (callbackfn: (value: number, index: number, array: Uint8Array) => number, thisArg?: any) => Uint8Array | Calls a defined callback function on each element of an array, and returns an array that contains the results. | | reduce | (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number) => number | Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. | | reduce | (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number) => number | | | reduce | <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U) => U | Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. | | reduceRight | (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number) => number | Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. | | reduceRight | (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number) => number | | | reduceRight | <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U) => U | Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. | | reverse | () => Uint8Array | Reverses the elements in an Array. | | set | (array: ArrayLike<number>, offset?: number | undefined) => void | Sets a value or an array of values. | | slice | (start?: number | undefined, end?: number | undefined) => Uint8Array | Returns a section of an array. | | some | (predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any) => boolean | Determines whether the specified callback function returns true for any element of an array. | | sort | (compareFn?: ((a: number, b: number) => number) | undefined) => this | Sorts an array. | | subarray | (begin?: number | undefined, end?: number | undefined) => Uint8Array | Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements at begin, inclusive, up to end, exclusive. | | toLocaleString | () => string | Converts a number to a string by using the current locale. | | toString | () => string | Returns a string representation of an array. | | valueOf | () => Uint8Array | Returns the primitive value of the specified object. |

ArrayLike

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

ArrayBufferTypes

Allowed ArrayBuffer types for the buffer of an ArrayBufferView and related Typed Arrays.

| Prop | Type | | ----------------- | --------------------------------------------------- | | ArrayBuffer | ArrayBuffer |

ArrayBuffer

Represents a raw buffer of binary data, which is used to store data for the different typed arrays. ArrayBuffers cannot be read from or written to directly, but can be passed to a typed array or DataView Object to interpret the raw buffer as needed.

| Prop | Type | Description | | ---------------- | ------------------- | ------------------------------------------------------------------------------- | | byteLength | number | Read-only. The length of the ArrayBuffer (in bytes). |

| Method | Signature | Description | | --------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------- | | slice | (begin: number, end?: number | undefined) => ArrayBuffer | Returns a section of an ArrayBuffer. |

TcpWriteAndReadResult

Result of writeAndRead().

  • bytesSent is the number of request bytes written. If the operation fails due to a pure timeout (no bytes received), bytesSent can still equal the request length; for other errors it is 0.
  • bytesReceived is the length of returned data (<= maxBytes).
  • matched indicates whether the expect pattern (if any) was found.

| Prop | Type | Description | | ------------------- | --------------------------- | ----------------------------------------------------------- | | error | boolean | | | errorMessage | string | null | | | bytesSent | number | | | bytesReceived | number | | | data | number[] | Received bytes (may be partial if timeout after some data). | | matched | boolean | True if the expect pattern was matched; false otherwise. |

TcpWriteAndReadOptions

Options for writeAndRead() request/response operation.

Behavior summary (parity across Android/iOS/Electron):

  • The request is written atomically with internal serialization (no interleaved writes across concurrent calls).
  • Response collection ends when ANY of these happens: • expect pattern is found (matched=true), or • maxBytes cap is reached, or • without expect: adaptive "until-idle" period elapses after last data, or • absolute timeout elapses (see errors below).
  • On timeout: • If no data arrived at all, the call fails with error=true and errorMessage resembling "connect timeout" and bytesSent equals the request length on Android/iOS/Electron; bytesReceived=0, matched=false. • If some data arrived before the deadline, the call resolves successfully with matched=false and returns the partial data.
  • suspendStreamDuringRR: when true, the active stream reader is temporarily stopped for the RR window to avoid racing over the same bytes; after RR it is resumed with the previous chunk size. Default is true on Android & iOS; Electron treats it as true by default as well.
  • expect: hex string like "0A0B0C" (case/spacing ignored) or a byte array.

| Prop | Type | Description | | --------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | data | number[] | Uint8Array | Request payload to send. | | timeout | number | Absolute RR timeout in ms. Defaults to 1000. | | maxBytes | number | Maximum number of bytes to accumulate and return. Defaults to 4096. | | expect | string | number[] | Uint8Array | Optional expected pattern. When provided, reading stops as soon as the accumulated buffer contains this pattern. Accepts: - number[] / Uint8Array: raw byte sequence - string: hex bytes (e.g., "0x1b40", "1B 40"), spacing and case ignored | | suspendStreamDuringRR | boolean | Temporarily suspend the stream reader during RR to avoid consuming reply in the stream. Defaults to true (Android default true; iOS behaves as if true; Electron defaults to true as well). |

TcpStartStopResult

Result of startRead()/stopRead().

| Prop | Type | Description | | ------------------ | --------------------------- | ---------------------------------------------- | | error | boolean | | | errorMessage | string | null | | | reading | boolean | Whether the stream reader is currently active. |

TcpStartReadOptions

Options for startRead().

  • chunkSize controls maximum size of a single tcpData event slice. Native implementations may micro-batch multiple small reads; Electron additionally splits a flushed batch into slices up to chunkSize to preserve consumer expectations.
  • readTimeout applies only on Android (socket SO_TIMEOUT while streaming). It is a no-op on iOS. Electron stores it for RR but does not apply to stream.

| Prop | Type | Description | | ----------------- | ------------------- | ------------------------------------------------------------------ | | chunkSize | number | Maximum bytes per emitted tcpData event. Default 4096. | | readTimeout | number | Stream read timeout (ms). Android: applies SO_TIMEOUT; iOS: no-op. |

PluginListenerHandle

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

TcpDataEvent

Emitted by the stream reader with micro-batched data chunks.

  • Data values are 0..255. The plugin may coalesce multiple small reads and then emit one or more events capped by chunkSize.

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

TcpDisconnectEvent

Emitted when the socket is closed or the plugin disconnects it.

  • reason: • 'manual' — disconnect() called or instance disposed. • 'remote' — the peer closed the connection (EOF). • 'error' — an I/O error occurred; error contains a message.
  • reading is false when this event fires.

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

Type Aliases

ArrayBufferLike

ArrayBufferTypes[keyof ArrayBufferTypes]