react-native-kozen-printer
v1.1.2
Published
React Native module for Kozen POS printer integration with enhanced features
Downloads
48
Maintainers
Readme
react-native-kozen-printer
React Native module for Kozen POS printer integration.
Installation
npm install react-native-kozen-printer
# or
yarn add react-native-kozen-printerRequirements
- Hardware: Kozen POS device with printer service installed
- Android: Minimum SDK 21 (API level 21)
- React Native: 0.72+
- Node.js: 18+
Setup Instructions
Choose the setup instructions based on your project type:
🚫 Expo Go (NOT Supported)
This library requires custom native code and cannot be used with Expo Go. You must use one of the supported workflows below.
✅ Option 1: Bare React Native (Recommended for Native Modules)
If you're using a bare React Native project (created with react-native init or ejected from Expo):
Step 1: Install the Library
npm install react-native-kozen-printerStep 2: Android Configuration
- Add the library to
android/settings.gradle:
include ':react-native-kozen-printer'
project(':react-native-kozen-printer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-kozen-printer/android')- Add the dependency in
android/app/build.gradle:
dependencies {
// ... other dependencies
implementation project(':react-native-kozen-printer')
}- Register the package in
MainApplication.javaorMainApplication.kt:
For Java (MainApplication.java):
import com.kozen.printer.KozenPrinterPackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
// ... existing code ...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new KozenPrinterPackage() // Add this line
);
}
}For Kotlin (MainApplication.kt):
import com.kozen.printer.KozenPrinterPackage
class MainApplication : Application(), ReactApplication {
override fun getPackages(): List<ReactPackage> {
val packages = PackageList(this).packages
packages.add(KozenPrinterPackage()) // Add this line
return packages
}
}- Add BLUETOOTH permission in
android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- ... rest of manifest ... -->
</manifest>Step 3: Rebuild the App
cd android
./gradlew clean
cd ..
npm run android✅ Option 2: Expo Development Build (Managed Workflow with Custom Native Code)
If you're using Expo with the managed workflow but need custom native code:
Step 1: Install Dependencies
# Install expo-dev-client (required for custom native modules)
npx expo install expo-dev-client
# Install the library
npm install react-native-kozen-printerStep 2: Add Config Plugin
Add the config plugin to your app.json or app.config.js. The plugin automatically handles:
- Copying AIDL files
- Including JAR dependency
- Configuring build.gradle
- Adding BLUETOOTH permissions
app.json:
{
"expo": {
"plugins": [
"react-native-kozen-printer"
],
"android": {
"permissions": ["BLUETOOTH", "BLUETOOTH_ADMIN"]
}
}
}app.config.js (if using config file):
export default {
expo: {
plugins: [
'react-native-kozen-printer'
],
android: {
permissions: ['BLUETOOTH', 'BLUETOOTH_ADMIN'],
},
},
};Step 3: Generate Native Directories
Run expo prebuild to generate the android/ and ios/ directories with native code:
npx expo prebuild --cleanThis command will:
- Generate the
android/directory with native Android project files - Automatically copy AIDL files to
android/app/src/main/aidl/ - Automatically include JAR dependency in
android/app/libs/ - Automatically configure build.gradle with sourceSets, repositories, and dependencies
- Automatically add BLUETOOTH permissions to AndroidManifest.xml
- Automatically link the native module via React Native autolinking
Note: The config plugin handles all native configuration automatically. No manual steps required!
Step 4: Create Development Build
Option A: Build with EAS (Recommended for production):
# Install EAS CLI if not already installed
npm install -g eas-cli
# Login to Expo
eas login
# Configure EAS
eas build:configure
# Build development client
eas build --profile development --platform androidOption B: Build locally:
npx expo run:androidThis will:
- Build the native Android app with the custom native module
- Install it on your connected device/emulator
- Start the Metro bundler
Step 5: Start Development
# Start Expo development server
npx expo start --dev-clientVerification
After expo prebuild, you can verify the automatic configuration:
- AIDL files should be in
android/app/src/main/aidl/com/xcheng/printerservice/ - JAR file should be in
android/app/libs/core-3.3.0.jar - build.gradle should include:
aidl.srcDirs = ['src/main/aidl']in sourceSetsflatDir { dirs 'libs' }in repositoriesimplementation files('libs/core-3.3.0.jar')in dependencies
- AndroidManifest.xml should include BLUETOOTH permissions
- Native module should be automatically registered (check
MainApplication.kt)
If any of these are missing, run npx expo prebuild --clean again.
✅ Option 3: Expo Bare Workflow
If you're using Expo's bare workflow (project initialized with expo init --template bare-minimum or ejected):
Step 1: Install the Library
npm install react-native-kozen-printerStep 2: Configure Android
Follow the same steps as Option 1: Bare React Native above, since bare workflow projects have full access to native directories.
Step 3: Add Permissions
Add BLUETOOTH permissions to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />Step 4: Rebuild
cd android
./gradlew clean
cd ..
npm run androidWorkflow Comparison
| Feature | Expo Go | Expo Dev Build | Expo Bare | Bare RN | |---------|---------|----------------|-----------|---------| | Custom Native Code | ❌ No | ✅ Yes | ✅ Yes | ✅ Yes | | Native Directories | ❌ No | ✅ Generated | ✅ Yes | ✅ Yes | | Setup Complexity | ❌ N/A | ✅ Automatic (Config Plugin) | ⚠️ Manual | ⚠️ Manual | | expo prebuild Required | ❌ N/A | ✅ Yes | ❌ No | ❌ No | | EAS Build | ❌ No | ✅ Recommended | ✅ Optional | ❌ No | | AIDL/JAR Auto-Config | ❌ N/A | ✅ Yes (Plugin) | ⚠️ Manual | ⚠️ Manual |
Key Differences:
- Expo Go: Cannot use this library (no custom native code support)
- Expo Dev Build: ✅ Easiest setup - Add plugin to
app.json, runexpo prebuild, everything is automatic! - Expo Bare: Has native directories, configure like bare React Native (manual setup)
- Bare RN: Full native access, manual configuration required
Usage
import KozenPrinterLibrary from 'react-native-kozen-printer';
// Connect and initialize printer
await KozenPrinterLibrary.prepare();
// Print text
await KozenPrinterLibrary.printText('Hello World');
// Print QR code
await KozenPrinterLibrary.printQRCode('https://example.com', 8, 'middle');
// Print barcode
await KozenPrinterLibrary.printBarcode(
'123456789',
'CODE128',
100,
2,
'textUnderBarcode'
);
// Print image
await KozenPrinterLibrary.printBitmapBase64(base64Image, 384);
// Set alignment
await KozenPrinterLibrary.setAlignment('center');
// Set font size
await KozenPrinterLibrary.setFontSize(32);
// Line wrap
await KozenPrinterLibrary.lineWrap(3);
// Cut paper
await KozenPrinterLibrary.cutPaper();
// Disconnect
await KozenPrinterLibrary.disconnect();API Reference
Core Functions
prepare()- Connect and initialize printerprinterInit()- Initialize printerprinterReset()- Reset printerdisconnect()- Disconnect from printerupdatePrinterState()- Get printer state
Information Functions
getPrinterInfo()- Get printer informationgetPrinterSerialNo()- Get serial numbergetPrinterVersion()- Get firmware versiongetServiceVersion()- Get service versiongetPrinterModal()- Get printer modelgetPrinterPaper()- Get paper width (58mm or 80mm)getPrintedLength()- Get printed length
Text Printing
setAlignment(alignment)- Set text alignment ('left' | 'center' | 'right')setFontSize(fontSize)- Set font sizesetBold(isBold)- Set bold textsetUnderline(isUnderline)- Set underlineprintText(text)- Print textprintTextWithFont(text, fontSize)- Print text with font sizeprintOriginalText(text)- Print original textprintColumnsText(texts, widths, alignments)- Print table rowprintColumnsString(texts, widths, alignments)- Print table row with width/alignment
Barcode/QR Printing
printBarcode(text, format, height, width, textPosition)- Print 1D barcodeprintQRCode(text, moduleSize, errorLevel)- Print QR code
Image Printing
printBitmapBase64(base64, pixelWidth)- Print image from base64printBitmapBase64Custom(base64, pixelWidth, type)- Print image with custom type
Paper Control
lineWrap(count)- Line wrapcutPaper()- Cut paper
Transaction Printing
enterPrinterBuffer(clear)- Enter transaction modeexitPrinterBuffer(commit)- Exit transaction modecommitPrinterBuffer()- Commit transaction
Kozen Enhanced Features
cashDrawerOpen()- Open cash drawerlcdSendCommand(command)- Send LCD commandblackLabelDetect()- Detect black labellabelLocate()- Locate labellabelOutput()- Output label
Raw Commands
sendRAWData(base64)- Send raw ESC/POS commands
Constants
MaxPixelWidth- Maximum pixel width for paper sizes ({ '58mm': 384, '80mm': 576 })defaultFontSize- Default font size (24)EventType- Event type constants for event listeners
Advanced Usage
Error Handling
import KozenPrinterLibrary from 'react-native-kozen-printer';
import { KozenPrinterError } from 'react-native-kozen-printer';
try {
await KozenPrinterLibrary.prepare();
await KozenPrinterLibrary.printText('Hello');
} catch (error) {
if (error instanceof KozenPrinterError) {
console.error('Printer error:', error.code, error.message);
} else {
console.error('Unknown error:', error);
}
}Event Listeners
import { onPrinterConnected, onPrinterError, removeAllListeners } from 'react-native-kozen-printer';
// Listen to connection events
const unsubscribeConnected = onPrinterConnected(() => {
console.log('Printer connected');
});
// Listen to error events
const unsubscribeError = onPrinterError((error) => {
console.error('Printer error:', error);
});
// Clean up listeners
// unsubscribeConnected();
// unsubscribeError();
// Or remove all:
// removeAllListeners();Table Printing Example
// Print a receipt table
await KozenPrinterLibrary.setAlignment('center');
await KozenPrinterLibrary.setBold(true);
await KozenPrinterLibrary.printText('RECEIPT');
await KozenPrinterLibrary.setBold(false);
await KozenPrinterLibrary.lineWrap(1);
// Table header
await KozenPrinterLibrary.printColumnsText(
['Item', 'Qty', 'Price'],
[20, 10, 15],
['left', 'center', 'right']
);
// Table rows
await KozenPrinterLibrary.printColumnsText(
['Product A', '2', '$10.00'],
[20, 10, 15],
['left', 'center', 'right']
);
await KozenPrinterLibrary.printColumnsText(
['Product B', '1', '$5.00'],
[20, 10, 15],
['left', 'center', 'right']
);
await KozenPrinterLibrary.lineWrap(2);
await KozenPrinterLibrary.cutPaper();Complete Receipt Example
async function printReceipt() {
try {
// Connect and initialize
await KozenPrinterLibrary.prepare();
// Header
await KozenPrinterLibrary.setAlignment('center');
await KozenPrinterLibrary.setBold(true);
await KozenPrinterLibrary.printText('MY STORE');
await KozenPrinterLibrary.setBold(false);
await KozenPrinterLibrary.printText('123 Main St');
await KozenPrinterLibrary.printText('Phone: 555-1234');
await KozenPrinterLibrary.lineWrap(1);
// Receipt details
await KozenPrinterLibrary.setAlignment('left');
await KozenPrinterLibrary.printText('Date: ' + new Date().toLocaleString());
await KozenPrinterLibrary.printText('Receipt #: 12345');
await KozenPrinterLibrary.lineWrap(1);
// Items
await KozenPrinterLibrary.printColumnsText(
['Item', 'Price'],
[25, 15],
['left', 'right']
);
await KozenPrinterLibrary.printText('--------------------------------');
await KozenPrinterLibrary.printColumnsText(
['Product 1', '$10.00'],
[25, 15],
['left', 'right']
);
await KozenPrinterLibrary.printColumnsText(
['Product 2', '$5.00'],
[25, 15],
['left', 'right']
);
await KozenPrinterLibrary.printText('--------------------------------');
await KozenPrinterLibrary.setBold(true);
await KozenPrinterLibrary.printColumnsText(
['Total', '$15.00'],
[25, 15],
['left', 'right']
);
await KozenPrinterLibrary.setBold(false);
await KozenPrinterLibrary.lineWrap(2);
// QR Code
await KozenPrinterLibrary.setAlignment('center');
await KozenPrinterLibrary.printQRCode('https://example.com/receipt/12345', 8, 'middle');
await KozenPrinterLibrary.lineWrap(2);
// Footer
await KozenPrinterLibrary.printText('Thank you for your purchase!');
await KozenPrinterLibrary.lineWrap(3);
await KozenPrinterLibrary.cutPaper();
// Disconnect
await KozenPrinterLibrary.disconnect();
} catch (error) {
console.error('Print error:', error);
}
}Testing
Unit Tests
Run unit tests with mocked NativeModules:
npm testHardware Tests
For testing with actual hardware, use the hardware test suite:
import { runHardwareTests } from 'react-native-kozen-printer/src/__tests__/hardware/PrinterHardwareTest';
// Run all hardware tests
await runHardwareTests();Development
Building the Library
# Build TypeScript to JavaScript
npm run build
# Type check without building
npm run typecheck
# Run linter
npm run lint
# Clean build artifacts
npm run cleanBuild System
This library uses react-native-builder-bob for building. The build system generates:
- CommonJS format (
lib/commonjs/) - ES Modules format (
lib/module/) - TypeScript definitions (
lib/typescript/)
Troubleshooting
Expo-Specific Issues
"Module not found" or "Native module not linked" in Expo Dev Build
Solution:
Ensure the config plugin is added to
app.json:{ "expo": { "plugins": ["react-native-kozen-printer"] } }Run prebuild with clean to regenerate native directories:
npx expo prebuild --cleanVerify the plugin ran successfully - check that:
- AIDL files exist in
android/app/src/main/aidl/ - JAR file exists in
android/app/libs/core-3.3.0.jar build.gradleincludes the AIDL sourceSets and JAR dependency
- AIDL files exist in
Rebuild the development client:
npx expo run:android # OR eas build --profile development --platform androidIf still not working, verify autolinking:
npx expo-modules-autolinking verify -vLook for
react-native-kozen-printerin the output.
"expo prebuild" overwrites manual changes
Solution:
- ✅ Use the config plugin - All native configuration is handled automatically
- ✅ Use
app.config.jsorapp.jsonfor configuration instead of manually editing native files - ✅ The plugin is idempotent - Safe to run
expo prebuildmultiple times - ⚠️ Don't manually edit files that the plugin manages (AIDL, JAR, build.gradle sections)
Development build doesn't include the library
Solution:
Verify config plugin is in app.json:
{ "expo": { "plugins": ["react-native-kozen-printer"] } }Clean and regenerate native directories:
npx expo prebuild --cleanVerify plugin output - Check prebuild logs for
[KozenPrinter]messagesVerify files were copied:
android/app/src/main/aidl/com/xcheng/printerservice/should existandroid/app/libs/core-3.3.0.jarshould exist
Verify
node_modules/react-native-kozen-printerexistsCheck that
android/settings.gradleincludes the module (should be auto-generated by React Native autolinking)Rebuild the development client
General Issues
Printer service not found
Ensure the Kozen printer service app is installed on the device. The service package is com.xcheng.printerservice.
Check service installation:
adb shell pm list packages | grep xchengConnection failed
- Check that the printer service is running
- Verify BLUETOOTH permission is granted in Android settings
- Ensure the device is a Kozen POS device with printer hardware
- Check Android logcat for connection errors:
adb logcat | grep -i printer
Build errors
For Bare React Native / Expo Bare:
- Ensure
android/settings.gradleincludes the:react-native-kozen-printermodule - Verify
android/app/build.gradlehas the dependency - Check that AIDL files are in the correct location
- Clean build:
cd android && ./gradlew clean && cd ..
For Expo Dev Build:
- ✅ Ensure config plugin is in app.json -
"plugins": ["react-native-kozen-printer"] - Run
npx expo prebuild --cleanto regenerate native directories with plugin applied - Verify plugin copied AIDL files and JAR dependency
- Ensure you're using a development build, not Expo Go
- Rebuild the development client after configuration changes
"Package not found" or linking errors
- Verify the library is installed:
npm list react-native-kozen-printer - Clear Metro bundler cache:
npm start -- --reset-cache - Clean and rebuild:
# For bare React Native cd android && ./gradlew clean && cd .. # For Expo npx expo prebuild --clean
TypeScript errors
If you see TypeScript errors about missing types:
- Ensure you're using TypeScript 4.8+
- Restart your TypeScript server in your IDE
- Run
npm run typecheckto verify types
License
MIT
