A React Native module for ESC/POS thermal printers supporting both iOS and Android platforms.
- Cross-platform support (iOS and Android)
- Multiple connection types (USB, Bluetooth, Network)
- Text printing with formatting options
- Image printing
- Barcode and QR code printing
- Receipt templates
- Paper control (cut, feed)
- Cash drawer control
- Raw command support
# Using npm
npm install react-native-pos-printer --save
# Using yarn
yarn add react-native-pos-printerThis module supports auto-linking for React Native 0.60 and above. All required SDK files are included in the package.
- Install the pods:
cd ios && pod install- Add the following to your Info.plist:
<key>UISupportedExternalAccessoryProtocols</key>
<array>
<string>com.epson.escpos</string>
</array>- For Bluetooth functionality, add the following to your Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to connect to thermal printers</string>This module supports auto-linking for React Native 0.60 and above. All required SDK files are included in the package.
- Add the following permissions to your
AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.usb.host" />- For Android 6.0+ (API level 23+), you'll need to request runtime permissions for Bluetooth and Location:
import { PermissionsAndroid } from 'react-native';
const requestBluetoothPermissions = async () => {
try {
const granted = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
]);
return Object.values(granted).every(
val => val === PermissionsAndroid.RESULTS.GRANTED
);
} catch (err) {
console.warn(err);
return false;
}
};import PosPrinter, { PrinterConnectionType, TextAlignment } from 'react-native-pos-printer';
// Discover printers
const discoverPrinters = async () => {
try {
const printers = await PosPrinter.getAvailablePrinters(PrinterConnectionType.ALL);
console.log('Available printers:', printers);
return printers;
} catch (error) {
console.error('Error discovering printers:', error);
return [];
}
};
// Connect to a printer
const connectToPrinter = async (printer) => {
try {
const connectedPrinter = await PosPrinter.connectToPrinter(printer);
console.log('Connected to printer:', connectedPrinter);
return true;
} catch (error) {
console.error('Error connecting to printer:', error);
return false;
}
};
// Print text
const printText = async () => {
try {
await PosPrinter.printText('Hello, World!', {
alignment: TextAlignment.CENTER,
fontSize: 2,
bold: true
});
return true;
} catch (error) {
console.error('Error printing text:', error);
return false;
}
};
// Print image
const printImage = async (imageUri) => {
try {
await PosPrinter.printImage(imageUri, {
width: 300,
alignment: TextAlignment.CENTER
});
return true;
} catch (error) {
console.error('Error printing image:', error);
return false;
}
};
// Print barcode
const printBarcode = async () => {
try {
await PosPrinter.printBarcode('1234567890', 'code128', {
width: 2,
height: 100,
printText: true
});
return true;
} catch (error) {
console.error('Error printing barcode:', error);
return false;
}
};
// Print QR code
const printQRCode = async () => {
try {
await PosPrinter.printQRCode('https://example.com', {
size: 6,
errorCorrection: 1
});
return true;
} catch (error) {
console.error('Error printing QR code:', error);
return false;
}
};
// Print complete receipt
const printReceipt = async () => {
try {
const receipt = {
items: [
{
type: 'text',
data: 'RECEIPT',
options: {
alignment: TextAlignment.CENTER,
fontSize: 2,
bold: true
}
},
{
type: 'text',
data: '--------------------------------',
options: {
alignment: TextAlignment.CENTER
}
},
{
type: 'text',
data: 'Item 1 $10.00',
options: {
alignment: TextAlignment.LEFT
}
},
{
type: 'text',
data: 'Item 2 $5.00',
options: {
alignment: TextAlignment.LEFT
}
},
{
type: 'text',
data: '--------------------------------',
options: {
alignment: TextAlignment.CENTER
}
},
{
type: 'text',
data: 'TOTAL $15.00',
options: {
alignment: TextAlignment.LEFT,
bold: true
}
},
{
type: 'text',
data: 'Thank you for your purchase!',
options: {
alignment: TextAlignment.CENTER
}
},
{
type: 'qrcode',
data: 'https://example.com/receipt/123',
options: {
alignment: TextAlignment.CENTER,
size: 6
}
}
],
cutPaper: true,
feedLines: 3
};
await PosPrinter.printReceipt(receipt);
return true;
} catch (error) {
console.error('Error printing receipt:', error);
return false;
}
};
// Cut paper
const cutPaper = async () => {
try {
await PosPrinter.cutPaper('full');
return true;
} catch (error) {
console.error('Error cutting paper:', error);
return false;
}
};
// Open cash drawer
const openCashDrawer = async () => {
try {
await PosPrinter.openCashDrawer();
return true;
} catch (error) {
console.error('Error opening cash drawer:', error);
return false;
}
};getAvailablePrinters(type)- Get available printers by typeconnectToPrinter(printerInfo)- Connect to a specific printerdisconnectPrinter()- Disconnect from the current printergetCurrentPrinter()- Get currently connected printer informationgetPrinterStatus()- Get current printer statusprintText(text, options)- Print text with formatting optionsprintImage(imageUri, options)- Print image from URIprintReceipt(receiptData)- Print complete receipt (text + images)printBarcode(data, type, options)- Print barcodeprintQRCode(data, options)- Print QR codecutPaper(cutType)- Cut paperfeedPaper(lines)- Feed paper by number of linessendCommand(command)- Send raw ESC/POS commandopenCashDrawer()- Open connected cash drawer
USB- USB connectionBLUETOOTH- Bluetooth connectionNETWORK- Network connectionALL- All connection types
CONNECTED- Printer is connectedDISCONNECTED- Printer is disconnectedPAPER_EMPTY- Printer is out of paperCOVER_OPEN- Printer cover is openPRINTER_ERROR- Printer has an error
UPC_A- UPC-A barcodeUPC_E- UPC-E barcodeEAN13- EAN-13 barcodeJAN13- JAN-13 barcodeEAN8- EAN-8 barcodeJAN8- JAN-8 barcodeCODE39- Code 39 barcodeITF- ITF barcodeCODABAR- Codabar barcodeCODE93- Code 93 barcodeCODE128- Code 128 barcodeGS1_128- GS1-128 barcodeGS1_DATABAR_OMNIDIRECTIONAL- GS1 DataBar Omnidirectional barcodeGS1_DATABAR_TRUNCATED- GS1 DataBar Truncated barcodeGS1_DATABAR_LIMITED- GS1 DataBar Limited barcodeGS1_DATABAR_EXPANDED- GS1 DataBar Expanded barcode
LEFT- Left alignmentCENTER- Center alignmentRIGHT- Right alignment
FULL- Full cutPARTIAL- Partial cut
PrinterEvents.addPrinterStatusListener(callback)- Add printer status listenerPrinterEvents.addPrinterConnectionListener(callback)- Add printer connection listenerPrinterEvents.removePrinterStatusListener(listenerId)- Remove printer status listenerPrinterEvents.removePrinterConnectionListener(listenerId)- Remove printer connection listener
If you encounter any issues, please refer to the TROUBLESHOOTING.md file.
MIT