npm package: @ruhiverse/thermal-printer-plugin
Description: Capacitor plugin for thermal printing via USB and Bluetooth
Author: Paresh Gami
Latest version: 1.0.18

# @ruhiverse/thermal-printer-plugin

Capacitor plugin for thermal printing via USB and Bluetooth connections. Supports ESC/POS formatted text printing.

## Installation

```bash
npm install @ruhiverse/thermal-printer-plugin
npx cap sync
```

## Usage

### Import the plugin

```typescript
import { ThermalPrinter } from '@ruhiverse/thermal-printer-plugin';
```

### Print via USB

```typescript
import { ThermalPrinter } from '@ruhiverse/thermal-printer-plugin';

// Print text using USB connection
await ThermalPrinter.printByUsb({
  textToPrint: '[C]<b>Hello World</b>\n[C]This is a test print',
});
```

### Print via Bluetooth

```typescript
import { ThermalPrinter } from '@ruhiverse/thermal-printer-plugin';

// Print text using Bluetooth connection
await ThermalPrinter.printByBluetooth({
  textToPrint: '[C]<b>Hello World</b>\n[C]This is a test print',
});
```

### ESC/POS Formatting

The plugin supports ESC/POS formatting commands. Here are some examples:

```typescript
// Center align text
'[C]Centered Text';

// Bold text
'<b>Bold Text</b>';

// Multiple lines
'Line 1\nLine 2\nLine 3';

// Combined formatting
'[C]<b>Centered Bold Text</b>\n[L]Left aligned text';
```

Common formatting tags:

- `[C]` - Center align
- `[L]` - Left align
- `[R]` - Right align
- `<b>text</b>` - Bold
- `<u>text</u>` - Underline
- `<font size='big'>text</font>` - Big font

### Printer Selection

You can list available printers and select one by its address (Bluetooth) or name (USB).

```typescript
// List Bluetooth printers
const { printers } = await ThermalPrinter.listBluetoothPrinters();
console.log('Available Bluetooth printers:', printers);

// Print to a specific Bluetooth printer
await ThermalPrinter.printByBluetooth({
  textToPrint: '[C]Hello from specific printer',
  address: printers[0].address, // MAC address
});

// List USB printers
const { printers: usbPrinters } = await ThermalPrinter.listUsbPrinters();
console.log('Available USB printers:', usbPrinters);

// Print to a specific USB printer
await ThermalPrinter.printByUsb({
  textToPrint: '[C]Hello from specific USB printer',
  name: usbPrinters[0].name, // Device name
});
```

### Printer Width (2", 3", 4")

For correct alignment and line wrapping, specify your printer's paper width. Default is 3 inch (80mm).

```typescript
// 2 inch (58mm) printer
await ThermalPrinter.printByBluetooth({
  textToPrint: '[C]Receipt\n[L]Item[R]Price',
  address: printerAddress,
  printerWidthMM: 58,
  printerNbrCharactersPerLine: 32,
});

// 3 inch (80mm) - default, no need to specify
await ThermalPrinter.printByBluetooth({
  textToPrint: '[C]Receipt\n[L]Item[R]Price',
  address: printerAddress,
});

// 4 inch (112mm) printer
await ThermalPrinter.printByBluetooth({
  textToPrint: '[C]Receipt\n[L]Item[R]Price',
  address: printerAddress,
  printerWidthMM: 112,
  printerNbrCharactersPerLine: 64,
});
```

## API

### printByUsb(printObject)

Print text using USB connection.

| Param           | Type          | Description                         |
| --------------- | ------------- | ----------------------------------- |
| **printObject** | `PrintObject` | Object containing options for print |

**Returns:** `Promise<void>`

### printByBluetooth(printObject)

Print text using Bluetooth connection.

| Param           | Type          | Description                         |
| --------------- | ------------- | ----------------------------------- |
| **printObject** | `PrintObject` | Object containing options for print |

**Returns:** `Promise<void>`

### listBluetoothPrinters()

Returns a list of paired Bluetooth printers.

**Returns:** `Promise<{ printers: { name: string, address: string }[] }>`

### listUsbPrinters()

Returns a list of connected USB printers.

**Returns:** `Promise<{ printers: { name: string, address: string }[] }>`

### PrintObject

| Prop                          | Type     | Description                                                                 |
| ----------------------------- | -------- | --------------------------------------------------------------------------- |
| **textToPrint**               | `string` | Text to print. Supports ESC/POS formatting commands.                         |
| **address**                   | `string` | (Optional) Bluetooth MAC address of the printer (for Bluetooth).             |
| **name**                      | `string` | (Optional) USB device name of the printer (for USB).                         |
| **printerWidthMM**            | `number` | (Optional) Paper width in mm. 58=2", 80=3", 112=4". Default: 80.              |
| **printerNbrCharactersPerLine**| `number` | (Optional) Chars per line. 32=2", 48=3", 64=4". Default: 48.                 |

## Platform Support

| Platform | Bluetooth | USB | Printer Discovery |
| -------- | --------- | --- | ----------------- |
| Android  | ✅         | ✅   | ✅ (paired + scan) |
| iOS      | ✅ (MFi & BLE) | ✅ (MFi only) | ✅ (MFi + BLE scan) |
| Web      | ❌         | ❌   | ❌                 |

## Android Setup

### Permissions

The plugin declares the following permissions in its `AndroidManifest.xml`:

- `BLUETOOTH`
- `BLUETOOTH_ADMIN`
- `BLUETOOTH_CONNECT` (Android 12+)
- `BLUETOOTH_SCAN` (Android 12+)
- `ACCESS_FINE_LOCATION` (required for Bluetooth scanning on Android 6-11)
- `ACCESS_COARSE_LOCATION`
- `USB_PERMISSION`

The plugin automatically requests Bluetooth permissions at runtime when needed.

### USB Printing

1. Connect your thermal printer via USB
2. Grant USB permission when prompted
3. The plugin will automatically detect and connect to the printer

### Bluetooth Printing

1. Pair your thermal printer with the device via **Android Settings > Bluetooth**
2. Use `listBluetoothPrinters()` to get the list of paired devices
3. Use `printByBluetooth()` with the printer's `address` to print, or omit `address` to use the first paired printer

## iOS Setup

### Required Info.plist Configuration

Add the following keys to your app's `Info.plist`. **Without these, Bluetooth will not work on iOS.**

```xml
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth access to connect to thermal printers.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth access to connect to thermal printers.</string>
<key>UISupportedExternalAccessoryProtocols</key>
<array>
    <string>com.epson.escpos</string>
    <string>com.starmicronics.starprnt</string>
</array>
```

| Key | Required | Description |
| --- | -------- | ----------- |
| `NSBluetoothAlwaysUsageDescription` | **Yes** | iOS will silently block Bluetooth access without this. Triggers the permission dialog. |
| `NSBluetoothPeripheralUsageDescription` | **Yes** | Required for connecting to Bluetooth peripherals (iOS 12 and earlier). |
| `UISupportedExternalAccessoryProtocols` | **Yes** (for MFi printers) | Lists the protocol strings your printer supports. Update with your printer's protocols. |

### iOS Bluetooth Printing

The plugin supports two types of Bluetooth connections on iOS:

**MFi / ExternalAccessory printers (classic Bluetooth):**
- Requires the printer to be MFi-certified (Made for iPhone)
- Uses the ExternalAccessory framework
- Printer must be paired in iOS Settings > Bluetooth
- Protocol strings must be listed in `UISupportedExternalAccessoryProtocols`

**BLE printers (Bluetooth Low Energy):**
- Uses CoreBluetooth framework
- Discovered via BLE scanning (4-second scan)
- Use the `address` from `listBluetoothPrinters()` when calling `printByBluetooth()`

### iOS USB Printing

USB printing on iOS requires MFi (Made for iPhone) certification for the printer. The printer is accessed through the ExternalAccessory framework.

### iOS Troubleshooting

| Issue | Solution |
| ----- | -------- |
| `listBluetoothPrinters()` returns empty | Make sure `NSBluetoothAlwaysUsageDescription` is in your Info.plist and Bluetooth permission is granted |
| Printer not found (MFi) | Verify the printer's protocol string is listed in `UISupportedExternalAccessoryProtocols` |
| Printer not found (BLE) | Ensure the printer is powered on and in range. BLE scan runs for 4 seconds |
| Permission dialog not showing | Delete and reinstall the app to reset permissions |

## Local Development

### Testing Locally Before Publishing

1. **Link the plugin locally:**

```bash
cd path/to/thermal-printer-plugin
npm link
```

2. **In your Ionic/Capacitor project:**

```bash
cd path/to/your-project
npm link @ruhiverse/thermal-printer-plugin
npx cap sync
```

3. **Build and test:**

```bash
npx cap run android
npx cap run ios
```

### Alternative: Install from local path

```bash
npm install path/to/thermal-printer-plugin
npx cap sync
```

## Development

### Build

```bash
npm run build
```

### Lint

```bash
npm run lint
```

### Format

```bash
npm run fmt
```

## License

MIT

## Author

**Paresh Gami**  
Company: Ruhiverse  
Website: https://ruhiverse.com