
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
capacitor-zebra-bluetooth
Advanced tools
Capacitor plugin for Zebra thermal printer communication via Classic Bluetooth. Supports iOS (ExternalAccessory) and Android (Bluetooth SPP) with ZPL command support.
A Capacitor plugin for communicating with Zebra thermal printers via Classic Bluetooth. Supports both iOS and Android platforms with full ZPL (Zebra Programming Language) command support.
This plugin works with Zebra mobile and desktop printers that support Bluetooth Classic (SPP profile), including:
npm install capacitor-zebra-bluetooth
npx cap sync
Add the Zebra Bluetooth protocol string to your ios/App/App/Info.plist:
<key>UISupportedExternalAccessoryProtocols</key>
<array>
<string>com.zebra.rawport</string>
</array>
Also add the Bluetooth usage description:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to connect to Zebra printers for label printing.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app uses Bluetooth to connect to Zebra printers for label printing.</string>
If you need to maintain printer connections in the background:
<key>UIBackgroundModes</key>
<array>
<string>external-accessory</string>
</array>
com.zebra.rawport protocolThe plugin automatically adds required permissions to your AndroidManifest.xml:
<!-- Bluetooth permissions (Android 11 and below) -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Bluetooth permissions (Android 12+) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Location permission (required for Bluetooth scanning on older versions) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissionsACCESS_FINE_LOCATION is required for Bluetooth scanningimport { CapacitorZebraBluetooth } from 'capacitor-zebra-bluetooth';
Discover all paired Zebra printers:
const result = await CapacitorZebraBluetooth.discoverPrinters();
console.log('Found printers:', result.printers);
// Result structure:
// {
// printers: [
// {
// friendlyName: "ZQ320-ABC123",
// manufacturer: "Zebra Technologies",
// modelName: "ZQ320",
// connected: false
// }
// ]
// }
const result = await CapacitorZebraBluetooth.connectToPrinter({
friendlyName: 'ZQ320-ABC123'
});
if (result.success) {
console.log('Connected successfully');
} else {
console.error('Connection failed:', result.message);
}
const { connected } = await CapacitorZebraBluetooth.isConnected();
console.log('Is connected:', connected);
const { printer } = await CapacitorZebraBluetooth.getConnectedPrinter();
if (printer) {
console.log('Connected to:', printer.friendlyName);
}
// Simple label example
const zpl = `
^XA
^FO50,50^A0N,50,50^FDHello World^FS
^FO50,120^BY3^BCN,100,Y,N,N^FD12345678^FS
^XZ
`;
const result = await CapacitorZebraBluetooth.sendZPL({ zpl });
if (result.success) {
console.log('Label printed successfully');
} else {
console.error('Print failed:', result.message);
}
const { status } = await CapacitorZebraBluetooth.getPrinterStatus();
console.log('Printer status:', {
connected: status.connected,
ready: status.ready,
printing: status.printing,
paperOut: status.paperOut,
headOpen: status.headOpen,
message: status.message
});
await CapacitorZebraBluetooth.disconnect();
Here's a complete example of a print service:
import { CapacitorZebraBluetooth, type ZebraPrinter } from 'capacitor-zebra-bluetooth';
class PrintService {
private selectedPrinter: ZebraPrinter | null = null;
async discoverAndConnect(): Promise<boolean> {
try {
// Discover printers
const { printers } = await CapacitorZebraBluetooth.discoverPrinters();
if (printers.length === 0) {
console.log('No printers found. Please pair a printer in device settings.');
return false;
}
// Connect to first available printer
this.selectedPrinter = printers[0];
const result = await CapacitorZebraBluetooth.connectToPrinter({
friendlyName: this.selectedPrinter.friendlyName
});
return result.success;
} catch (error) {
console.error('Error:', error);
return false;
}
}
async printLabel(text: string, barcode: string): Promise<boolean> {
// Check connection
const { connected } = await CapacitorZebraBluetooth.isConnected();
if (!connected) {
const success = await this.discoverAndConnect();
if (!success) return false;
}
// Generate ZPL
const zpl = `
^XA
^CI28
^FO50,50^A0N,40,40^FD${text}^FS
^FO50,100^BY2^BCN,80,Y,N,N^FD${barcode}^FS
^XZ
`;
// Send to printer
const result = await CapacitorZebraBluetooth.sendZPL({ zpl });
return result.success;
}
async checkPrinterReady(): Promise<boolean> {
const { status } = await CapacitorZebraBluetooth.getPrinterStatus();
if (status.paperOut) {
console.warn('Printer is out of paper');
return false;
}
if (status.headOpen) {
console.warn('Printer head is open');
return false;
}
return status.ready;
}
}
Here are some common ZPL commands:
| Command | Description | Example |
|---|---|---|
^XA | Start label format | ^XA |
^XZ | End label format | ^XZ |
^FO | Field origin (x,y position) | ^FO50,100 |
^FD | Field data | ^FDHello^FS |
^FS | Field separator (end field) | ^FS |
^A0N | Scalable font | ^A0N,50,50 |
^BC | Code 128 barcode | ^BCN,100,Y,N,N |
^BQ | QR Code | ^BQN,2,5 |
^BY | Bar code field default | ^BY3 |
^GB | Graphic box (line/rectangle) | ^GB200,3,3^FS |
^CI28 | UTF-8 character set | ^CI28 |
^LL | Label length | ^LL400 |
^PW | Print width | ^PW400 |
^XA
^CI28
^FO50,50^A0N,30,30^FDProduct: Widget^FS
^FO50,90^A0N,30,30^FDPrice: $9.99^FS
^XZ
^XA
^FO50,50^A0N,25,25^FDSKU: ABC123^FS
^FO50,80^BY2^BCN,80,Y,N,N^FDABC123^FS
^XZ
^XA
^FO50,50^BQN,2,5^FDQA,https://example.com^FS
^XZ
^XA
^CI28
^PW400
^LL800
^FO50,30^A0N,30,30^FDCompany Name^FS
^FO50,70^GB300,2,2^FS
^FO50,90^A0N,20,20^FDItem 1^FS
^FO300,90^A0N,20,20^FD$10.00^FS
^FO50,120^A0N,20,20^FDItem 2^FS
^FO300,120^A0N,20,20^FD$15.00^FS
^FO50,160^GB300,2,2^FS
^FO50,180^A0N,25,25^FDTotal: $25.00^FS
^XZ
discoverPrinters(): Promise<{ printers: ZebraPrinter[] }>
Discover available Zebra printers via Classic Bluetooth. On iOS, only previously paired printers will be returned.
connectToPrinter(options: { friendlyName: string }): Promise<{ success: boolean; message?: string }>
Connect to a Zebra printer by its friendly name.
disconnect(): Promise<{ success: boolean }>
Disconnect from the currently connected printer.
isConnected(): Promise<{ connected: boolean }>
Check if a printer is currently connected.
getConnectedPrinter(): Promise<{ printer: ZebraPrinter | null }>
Get the currently connected printer information.
sendZPL(options: { zpl: string }): Promise<{ success: boolean; message?: string }>
Send ZPL commands to the connected printer.
getPrinterStatus(): Promise<{ status: PrinterStatus }>
Get the current printer status including paper and head status.
interface ZebraPrinter {
friendlyName: string;
manufacturer?: string;
modelName?: string;
serialNumber?: string;
connected: boolean;
}
interface PrinterStatus {
connected: boolean;
ready: boolean;
printing: boolean;
paperOut: boolean;
headOpen: boolean;
message?: string;
}
^XA and ^XZ tags are presentUISupportedExternalAccessoryProtocols includes com.zebra.rawportgit checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)# Install dependencies
npm install
# Build the plugin
npm run build
# Watch for changes
npm run watch
# Run linter
npm run lint
# Format code
npm run fmt
MIT License - see the LICENSE file for details.
FAQs
Capacitor plugin for Zebra thermal printer communication via Classic Bluetooth. Supports iOS (ExternalAccessory) and Android (Bluetooth SPP) with ZPL command support.
The npm package capacitor-zebra-bluetooth receives a total of 0 weekly downloads. As such, capacitor-zebra-bluetooth popularity was classified as not popular.
We found that capacitor-zebra-bluetooth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.