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

@fedejm/capacitor-esc-pos-printer

v0.2.4

Published

CapacitorJS wrapper for ESC POS (native) printers.

Readme

capacitor-esc-pos-printer

CapacitorJS wrapper for ESC POS (native) printers.

Features

  • Bluetooth printing - Connect to Bluetooth ESC/POS printers (Android, iOS)
  • USB printing - Connect to USB ESC/POS printers via USB Host API (Android only)
  • Raw data sending - Send raw ESC/POS commands for full control
  • Bi-directional communication - Read responses from printer
  • Permission management - Built-in USB permission request flow

Install

npm install @fedejm/capacitor-esc-pos-printer
npx cap sync

Platform Support

| Feature | Android | iOS | Web | |------------|---------|---------|---------| | Bluetooth | Yes | Yes | Limited | | USB | Yes | No | No | | Network | Planned | Planned | Planned |

Android Requirements

  • Bluetooth: Requires BLUETOOTH_CONNECT and BLUETOOTH_SCAN permissions (Android 12+)
  • USB: Requires android.hardware.usb.host feature (automatically declared as optional)

iOS Requirements

  • Bluetooth printing is supported via CoreBluetooth framework
  • USB printing is not available on iOS

Usage

Bluetooth Printer

import { EscPosPrinter, BluetoothPrinter } from '@fedejm/capacitor-esc-pos-printer';

// Request Bluetooth enable (Android)
await EscPosPrinter.requestBluetoothEnable();

// Get paired Bluetooth printers
const { devices } = await EscPosPrinter.getBluetoothPrinterDevices();
console.log('Found printers:', devices);

// Create and connect to a printer
const printer = new BluetoothPrinter(devices[0].address);
await printer.link();
await printer.connect();

// Send ESC/POS commands
await printer.send([0x1B, 0x40]); // Initialize printer
await printer.send([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
await printer.send([0x0A]); // Line feed

// Disconnect
await printer.disconnect();
await printer.dispose();

USB Printer (Android only)

import { EscPosPrinter, UsbPrinter } from '@fedejm/capacitor-esc-pos-printer';

// Get connected USB printers
const { devices } = await EscPosPrinter.getUsbPrinterDevices();
console.log('Found USB printers:', devices);

// Find a device and check permission status
const device = devices[0];
if (!device.hasPermission) {
  // Request USB permission
  const { value: granted } = await EscPosPrinter.requestUsbPermission({ 
    address: device.id 
  });
  
  if (!granted) {
    console.log('USB permission denied for:', device.name);
    return;
  }
}

// Create and connect to a USB printer
const printer = new UsbPrinter(device.id);
await printer.link();
await printer.connect();

// Send ESC/POS commands (same as Bluetooth)
await printer.send([0x1B, 0x40]); // Initialize printer
await printer.send([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
await printer.send([0x0A]); // Line feed

// Disconnect
await printer.disconnect();
await printer.dispose();

Connection Lifecycle

The printer connection follows this lifecycle:

┌─────────┐     link()     ┌────────┐    connect()    ┌───────────┐
│ Created ├───────────────►│ Linked ├─────────────────►│ Connected │
└─────────┘                └────────┘                  └───────────┘
                                                            │
                                                    disconnect()
                                                            │
                                                            ▼
                           ┌─────────┐   dispose()   ┌────────────┐
                           │Disposed │◄──────────────┤Disconnected│
                           └─────────┘               └────────────┘
  1. Create - Instantiate BluetoothPrinter or UsbPrinter with device address
  2. Link - Register with native plugin (link())
  3. Connect - Open connection to physical device (connect())
  4. Send/Read - Perform I/O operations (send(), read())
  5. Disconnect - Close connection (disconnect())
  6. Dispose - Unregister from plugin (dispose())

API

requestBluetoothEnable()

requestBluetoothEnable() => Promise<ValueResult<boolean>>

Returns: Promise<ValueResult<boolean>>


getBluetoothPrinterDevices()

getBluetoothPrinterDevices() => Promise<BluetoothDevicesResult>

Returns: Promise<BluetoothDevicesResult>


getUsbPrinterDevices()

getUsbPrinterDevices() => Promise<UsbDevicesResult>

Discovers USB devices that could be ESC/POS printers. Returns devices with bulk OUT endpoints that may be suitable for printing.

Returns: Promise<UsbDevicesResult>


requestUsbPermission(...)

requestUsbPermission(options: WithAddress) => Promise<ValueResult<boolean>>

Requests USB permission for a specific device. Note: May require user interaction via system UI.

| Param | Type | | ------------- | --------------------------------------------------- | | options | WithAddress |

Returns: Promise<ValueResult<boolean>>


createPrinter(...)

createPrinter(options: CreatePrinterOptions) => Promise<ValueResult<string>>

| Param | Type | | ------------- | --------------------------------------------------------------------- | | options | CreatePrinterOptions |

Returns: Promise<ValueResult<string>>


disposePrinter(...)

disposePrinter(options: WithHashKey) => Promise<ValueResult<boolean>>

| Param | Type | | ------------- | --------------------------------------------------- | | options | WithHashKey |

Returns: Promise<ValueResult<boolean>>


isPrinterConnected(...)

isPrinterConnected(options: WithHashKey) => Promise<ValueResult<boolean>>

| Param | Type | | ------------- | --------------------------------------------------- | | options | WithHashKey |

Returns: Promise<ValueResult<boolean>>


connectPrinter(...)

connectPrinter(options: WithHashKey) => Promise<void>

| Param | Type | | ------------- | --------------------------------------------------- | | options | WithHashKey |


disconnectPrinter(...)

disconnectPrinter(options: WithHashKey) => Promise<void>

| Param | Type | | ------------- | --------------------------------------------------- | | options | WithHashKey |


sendToPrinter(...)

sendToPrinter(options: SendToPrinterOptions) => Promise<void>

| Param | Type | | ------------- | --------------------------------------------------------------------- | | options | SendToPrinterOptions |


readFromPrinter(...)

readFromPrinter(options: WithHashKey) => Promise<ValueResult<number[]>>

| Param | Type | | ------------- | --------------------------------------------------- | | options | WithHashKey |

Returns: Promise<ValueResult<number[]>>


Interfaces

ValueResult

| Prop | Type | | ----------- | -------------- | | value | T |

BluetoothDevicesResult

| Prop | Type | | ------------- | ------------------------------------------------------------------------------------------------------------------- | | devices | { address: string; alias?: string; name: string; bondState: number; type: number; uuids: string[]; }[] |

UsbDevicesResult

Result from USB device discovery. Contains list of USB devices that could be ESC/POS printers.

| Prop | Type | | ------------- | ---------------------------- | | devices | UsbDeviceInfo[] |

UsbDeviceInfo

Information about a discovered USB device.

| Prop | Type | Description | | ---------------------- | -------------------- | -------------------------------------------------------------------------- | | id | string | Stable identifier for the device (format: "vendorId:productId:deviceName") | | name | string | Human-readable name (product name or fallback) | | vendorId | number | USB Vendor ID | | productId | number | USB Product ID | | deviceClass | number | USB Device Class | | deviceSubclass | number | USB Device Subclass | | deviceName | string | System device name/path | | manufacturerName | string | Manufacturer name if available | | hasPermission | boolean | Whether the app has USB permission for this device |

WithAddress

| Prop | Type | | ------------- | ------------------- | | address | string |

CreatePrinterOptions

| Prop | Type | Description | | -------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | connectionType | PrinterConnectionType | | | address | string | Address/identifier for the printer: - Bluetooth: MAC address (e.g., "00:11:22:33:44:55") - USB: Device identifier (e.g., "1234:5678:002") - Network: IP address and optional port (e.g., "192.168.1.100:9100") |

WithHashKey

| Prop | Type | | ------------- | ------------------- | | hashKey | string |

SendToPrinterOptions

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

Enums

PrinterConnectionType

| Members | Value | | --------------- | ------------------------ | | Bluetooth | 'bluetooth' | | Usb | 'usb' | | Network | 'network' |

Error Handling

All printer operations may throw a PrinterError with a specific error code:

import { PrinterError, PrinterErrorCode } from '@fedejm/capacitor-esc-pos-printer';

try {
  await printer.connect();
} catch (error) {
  if (error instanceof PrinterError) {
    switch (error.code) {
      case PrinterErrorCode.Connect:
        console.log('Connection failed');
        break;
      case PrinterErrorCode.NotConnected:
        console.log('Printer not connected');
        break;
      case PrinterErrorCode.Send:
        console.log('Failed to send data');
        break;
      case PrinterErrorCode.Read:
        console.log('Failed to read data');
        break;
      case PrinterErrorCode.Permissions:
        console.log('Permission denied');
        break;
      case PrinterErrorCode.DeviceNotFound:
        console.log('Device not found');
        break;
    }
  }
}

Error Code Reference

| Code | Name | Value | Description | |------|----------------|-------|---------------------------------------------------------------| | 1 | Connect | 1 | Failed to establish connection to the printer | | 2 | NotConnected | 2 | Attempted operation on disconnected printer | | 3 | Send | 3 | Failed to send data to the printer | | 4 | Read | 4 | Failed to read data from the printer | | 5 | Permissions | 5 | Required permission not granted (Bluetooth or USB) | | 6 | DeviceNotFound | 6 | Device not found or no longer available |

USB Permissions (Android)

USB devices require explicit permission from the user. The plugin provides a complete permission flow:

Checking Permission

const { devices } = await EscPosPrinter.getUsbPrinterDevices();
const device = devices.find(d => d.vendorId === 0x0483); // Find by vendor ID

if (device && !device.hasPermission) {
  console.log('Permission required for:', device.name);
}

Requesting Permission

// Request permission - triggers system dialog
const { value: granted } = await EscPosPrinter.requestUsbPermission({
  address: device.id
});

if (granted) {
  console.log('Permission granted!');
  // Refresh device list to update permission status
  const { devices: updated } = await EscPosPrinter.getUsbPrinterDevices();
} else {
  console.log('Permission denied by user');
}

Permission Flow Diagram

┌─────────────────────┐
│ getUsbPrinterDevices│
└──────────┬──────────┘
           │
           ▼
    ┌──────────────┐
    │hasPermission?│
    └──────┬───────┘
           │
     ┌─────┴─────┐
     │           │
    Yes         No
     │           │
     ▼           ▼
┌─────────┐  ┌────────────────────┐
│ Connect │  │requestUsbPermission│
└─────────┘  └─────────┬──────────┘
                       │
                       ▼
              ┌──────────────────┐
              │System Permission │
              │    Dialog        │
              └────────┬─────────┘
                       │
                 ┌─────┴─────┐
                 │           │
              Granted     Denied
                 │           │
                 ▼           ▼
            ┌─────────┐  ┌───────┐
            │ Connect │  │ Error │
            └─────────┘  └───────┘

Notes on USB Permission

  • Permission is granted per-device and persists until the app is uninstalled
  • If the device is unplugged and replugged, permission may need to be re-requested
  • The permission dialog is a system UI and cannot be customized
  • Permission requests are idempotent - multiple calls for already-permitted devices return immediately

Reading from Printer

Some printers support bi-directional communication. The read() method is best-effort:

// Send status request command
await printer.send([0x10, 0x04, 0x01]); // DLE EOT 1 (transmit status)

// Read response
const response = await printer.read();
if (response.length > 0) {
  console.log('Printer status:', response);
} else {
  console.log('No response (printer may not support reading)');
}

Note: Many USB ESC/POS printers do not implement a read endpoint. The read() method will return an empty array in such cases without throwing an error.

Future: Network Printing

Network/TCP printing is planned for a future release. The API design is already prepared:

// Future API (not yet implemented)
const printer = new NetworkPrinter('192.168.1.100:9100');
await printer.link();
await printer.connect();
// ... same send/read API

The PrinterConnectionType.Network enum value is already defined for forward compatibility.

Contributing

See CONTRIBUTING.md for development setup and contribution guidelines.

License

MIT