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

@mindfield/capacitor-osc

v1.0.0

Published

Capacitor 7 plugin for Open Sound Control (OSC) — Send and receive OSC messages via UDP

Downloads

49

Readme

@mindfield/capacitor-osc

npm version license

Capacitor 7 plugin for Open Sound Control (OSC) -- Send and receive OSC messages via UDP on Android and iOS.

Features

  • UDP send and receive -- Full bidirectional OSC communication over UDP
  • Complete OSC type system -- Int32, Float32, Float64, Int64, String, Blob, True, False, Nil
  • Auto-detection -- Numbers are automatically typed as Int32 or Float32; explicit type tags available when you need control
  • TypeScript-first -- Full type definitions with JSDoc documentation
  • Promise-based API -- Modern async/await interface, no callbacks
  • Event-driven receive -- Capacitor listener pattern for incoming messages
  • Zero configuration (Android) -- INTERNET permission is auto-added
  • Lightweight -- Android uses JavaOSC 0.9 (Maven Central), iOS uses Apple's Network framework (no external dependencies)

Supported Platforms

| Platform | Support | Minimum Version | |----------|---------|-----------------| | Android | Yes | API 23 (Android 6.0) | | iOS | Yes | iOS 14.0 | | Web | No | UDP is not available in browsers |

Installation

npm install @mindfield/capacitor-osc
npx cap sync

Platform Configuration

Android

No extra configuration needed. The INTERNET permission is automatically added by the plugin.

iOS

Add the local network usage description to your Info.plist:

<key>NSLocalNetworkUsageDescription</key>
<string>This app uses the local network to send and receive OSC messages.</string>

Quick Start

import { OSC } from '@mindfield/capacitor-osc';

// Send a message
await OSC.send({
  host: '192.168.1.100',
  port: 9000,
  message: { address: '/sensor/eda', args: [3.14, 'hello'] }
});

// Listen for messages
await OSC.startListening({ port: 8000 });
const handle = await OSC.addListener('message', (event) => {
  console.log(`${event.address}:`, event.args);
});

// Clean up
handle.remove();
await OSC.stopListening();

API Reference

startListening(options)

Start listening for incoming OSC messages on the given UDP port.

startListening(options: StartListeningOptions): Promise<void>

| Parameter | Type | Description | |-----------|------|-------------| | options.port | number | UDP port to listen on |

Throws an error with code BIND_FAILED if the port is already in use.

await OSC.startListening({ port: 8000 });

stopListening()

Stop listening for incoming OSC messages. No-op if not currently listening.

stopListening(): Promise<void>
await OSC.stopListening();

send(options)

Send an OSC message to the specified host and port.

send(options: SendOptions): Promise<void>

| Parameter | Type | Description | |-----------|------|-------------| | options.host | string | Target host IP address or hostname | | options.port | number | Target UDP port | | options.message | OSCMessage | The OSC message to send |

Throws an error with code SEND_FAILED on network errors.

await OSC.send({
  host: '192.168.1.100',
  port: 9000,
  message: {
    address: '/sensor/temperature',
    args: [36.5, 'celsius']
  }
});

getStatus()

Get the current status of the OSC plugin.

getStatus(): Promise<OSCStatusResult>

Returns an OSCStatusResult with isListening (boolean) and optionally listeningPort (number).

const status = await OSC.getStatus();
console.log(status.isListening, status.listeningPort);

addListener('message', ...)

Listen for incoming OSC messages. Requires startListening() to be called first.

addListener(
  eventName: 'message',
  listener: (event: OSCMessageEvent) => void
): Promise<PluginListenerHandle>

The OSCMessageEvent contains:

| Field | Type | Description | |-------|------|-------------| | address | string | OSC address of the received message | | args | OSCArgumentValue[] | Decoded arguments | | host | string | Sender IP address (always "" on Android — JavaOSC limitation) | | port | number | Sender port (always 0 on Android — JavaOSC limitation) | | timestamp | number | Receive timestamp (ms since epoch) |

const handle = await OSC.addListener('message', (event) => {
  if (event.address === '/sensor/eda') {
    console.log('EDA value:', event.args[0]);
  }
});

// Remove this listener
handle.remove();

addListener('error', ...)

Listen for OSC errors (bind failures, send errors, parse errors).

addListener(
  eventName: 'error',
  listener: (event: OSCErrorEvent) => void
): Promise<PluginListenerHandle>

The OSCErrorEvent contains:

| Field | Type | Description | |-------|------|-------------| | message | string | Human-readable error description | | code | string | Error code: BIND_FAILED, SEND_FAILED, or PARSE_ERROR |

await OSC.addListener('error', (event) => {
  console.error(`OSC error [${event.code}]: ${event.message}`);
});

removeAllListeners()

Remove all listeners for this plugin.

removeAllListeners(): Promise<void>
await OSC.removeAllListeners();

Type Reference

OSCTypedArg

Explicit type tag for OSC arguments. Use when auto-detection is insufficient.

interface OSCTypedArg {
  type: 'i' | 'f' | 'd' | 'h' | 's' | 'b' | 'T' | 'F' | 'N';
  value?: number | string | boolean | null;
}

OSCArgumentValue

A union type representing any OSC argument:

type OSCArgumentValue = number | string | boolean | null | OSCTypedArg;

OSCMessage

interface OSCMessage {
  address: string;           // OSC address pattern, e.g. "/sensor/eda"
  args?: OSCArgumentValue[]; // Arguments to include
}

OSCMessageEvent

interface OSCMessageEvent {
  address: string;           // OSC address of the received message
  args: OSCArgumentValue[];  // Decoded arguments
  host: string;              // Sender IP address
  port: number;              // Sender port
  timestamp: number;         // Receive timestamp (ms since epoch)
}

OSCErrorEvent

interface OSCErrorEvent {
  message: string;           // Human-readable error description
  code: 'BIND_FAILED' | 'SEND_FAILED' | 'PARSE_ERROR';
}

StartListeningOptions

interface StartListeningOptions {
  port: number;              // UDP port to listen on
}

SendOptions

interface SendOptions {
  host: string;              // Target host IP or hostname
  port: number;              // Target UDP port
  message: OSCMessage;       // The OSC message to send
}

OSCStatusResult

interface OSCStatusResult {
  isListening: boolean;      // Whether currently listening
  listeningPort?: number;    // Port being listened on, if listening
}

OSC Type System

The plugin supports the full OSC 1.0 type system. Primitive JS values are auto-detected; use OSCTypedArg for explicit control.

| JS Value | OSC Type | Tag | Notes | |----------|----------|-----|-------| | 42 (integer) | Int32 | i | Auto-detected via Number.isInteger() | | 3.14 (float) | Float32 | f | Auto-detected (non-integer number) | | 'hello' | String | s | | | true | True | T | | | false | False | F | | | null | Nil | N | | | { type: 'i', value: 42 } | Int32 | i | Explicit | | { type: 'f', value: 1.0 } | Float32 | f | Explicit -- forces float even for integer values | | { type: 'd', value: 3.14159265358979 } | Float64 | d | Explicit double precision | | { type: 'h', value: 9007199254740992 } | Int64 | h | Explicit 64-bit integer | | { type: 's', value: 'text' } | String | s | Explicit | | { type: 'b', value: 'SGVsbG8=' } | Blob | b | Base64-encoded binary data | | { type: 'T' } | True | T | Explicit (value ignored) | | { type: 'F' } | False | F | Explicit (value ignored) | | { type: 'N' } | Nil | N | Explicit (value ignored) |

When to Use Explicit Types

Auto-detection works well for most cases. Use explicit OSCTypedArg when:

  • You need Float32 for an integer value (e.g., { type: 'f', value: 1 } sends 1.0 as float)
  • You need Float64 double precision (not available via auto-detection)
  • You need Int64 for large integers (not available via auto-detection)
  • You need to send binary Blob data

Migration from cordova-plugin-osc

| cordova-plugin-osc | @mindfield/capacitor-osc | Notes | |---------------------|--------------------------|-------| | new OSC() | import { OSC } | Singleton, no instantiation needed | | osc.startListening(port, cb) | await OSC.startListening({ port }) | Promise-based, no callback | | osc.addListener(addr, cb) | await OSC.addListener('message', cb) | Global listener; filter by address in JS | | osc.send({...}) | await OSC.send({...}) | Similar structure, Promise return | | osc.stopListening() | await OSC.stopListening() | | | osc.close() | await OSC.stopListening() | Combined into one method | | Callback error handling | OSC.addListener('error', cb) | Dedicated error event |

Use Cases

  • Biofeedback -- Stream eSense sensor data (EDA, temperature) to Max/MSP, Pure Data, or custom visualizers
  • VJing and Visuals -- Control TouchDesigner, Resolume, or Processing sketches from a mobile device
  • Music Production -- Send control data to Ableton Live, SuperCollider, Reaktor, or any DAW with OSC support
  • Interactive Installations -- Bridge mobile sensors to desktop applications for real-time audience interaction
  • Research -- Forward physiological measurements to lab software (LabVIEW, OpenViBE, custom tools)

Contributing

See CONTRIBUTING.md for development setup and contribution guidelines.

License

MIT -- Mindfield Biosystems Ltd.