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

@rejaul/react-native-printer-kit

v0.3.1

Published

Direct Bluetooth POS/thermal (ESC/POS) printer integration for React Native on Android — print raw text, images, PDFs, and full HTML/CSS content including Bangla and other non-Latin scripts.

Readme

react-native-printer-kit

A professional-grade React Native module for printing directly to Bluetooth POS/thermal (ESC/POS) printers on Android devices only — no third-party printer app, no OS print dialog. Print raw text, images, PDFs, and full HTML/CSS content, including Bangla and other non-Latin scripts that ESC/POS printer fonts don't support natively.

Important: This library is exclusively for Android. Bluetooth Classic SPP + ESC/POS is an Android-specific integration; iOS does not expose the APIs this relies on.

npm version license Platform - Android Only Kotlin TypeScript

Why this exists

Most ESC/POS printer libraries only send raw text or a single pre-made image. They can't render real content — an actual HTML/CSS receipt layout, a PDF, or text in a script the printer's built-in font doesn't have (Bangla, Arabic, Hindi, etc.). This library renders your HTML/PDF to a bitmap on-device (Android's own WebView and PdfRenderer — no external rendering library) and sends it to the printer as a dithered ESC/POS raster image.

It's a thin React Native bridge over android-printer-kit, the native Kotlin library that does the actual work.

Features

  • Direct Bluetooth Classic (SPP) connection to any paired ESC/POS printer.
  • HTML → PDF → print pipeline, so you can print an actual styled receipt/report.
  • PDF → image → print pipeline via Android's built-in PdfRenderer.
  • Non-Latin text support (Bangla and others) via image-based rendering.
  • Persistent connection: the printer stays connected even if the app is swiped away from Recents (a foreground service keeps it alive).
  • Auto-reconnect: remembers the last connected printer and reconnects automatically next time the app starts.
  • Banded raster printing: images are sent in small, paced chunks, since many cheap ESC/POS boards silently drop large single print commands.
  • Type-safe: full TypeScript definitions, backed by a New Architecture TurboModule.

Platform Support

| Platform | Status | Details | |----------|--------|---------| | Android | Fully Supported | API Level 24+ required | | iOS | Not Supported | No Bluetooth Classic SPP / ESC/POS API equivalent |

Scope

This library speaks Bluetooth Classic SPP + ESC/POS — the standard used by virtually all budget Bluetooth receipt/thermal printers. It does not support Bluetooth LE printers, WiFi/network printers, USB-connected printers, or non-ESC/POS protocols (PCL/PostScript inkjet & laser printers).

Minimum Requirements

  • React Native >= 0.76 (New Architecture / TurboModules)
  • Android API Level >= 24 (Android 7.0+)
  • Kotlin 2.0.21+ (included in the build system)

Installation

npm install @rejaul/react-native-printer-kit
# or
yarn add @rejaul/react-native-printer-kit

Nothing to configure manually — all required Bluetooth and foreground-service permissions are declared by the underlying native library's manifest and merge in automatically. You still need to request the runtime BLUETOOTH_CONNECT (Android 12+) and POST_NOTIFICATIONS (Android 13+) permissions at runtime — requestBluetoothPermission() handles both in one call; see Permissions below.

Quick Start

import {
  hasBluetoothPermission,
  requestBluetoothPermission,
  getBondedBluetoothPrinters,
  connectPrinter,
  printText,
  printHtml,
} from '@rejaul/react-native-printer-kit';

async function printReceipt() {
  // 1. Make sure Bluetooth permission is granted (Android 12+)
  if (!hasBluetoothPermission()) {
    const granted = await requestBluetoothPermission();
    if (!granted) return;
  }

  // 2. List paired printers and connect to one
  const printers = getBondedBluetoothPrinters();
  if (printers.length === 0) return;
  await connectPrinter({ address: printers[0]!.address });

  // 3a. Print plain text
  await printText({ text: 'Hello from PrinterKit' });

  // 3b. Or print a full HTML receipt (Bangla, styling, everything)
  const ok = await printHtml({ html: myReceiptHtml });
  console.log('Printed:', ok);
}

Permissions

import {
  hasBluetoothPermission,
  requestBluetoothPermission,
} from '@rejaul/react-native-printer-kit';

// Synchronous check - always true below Android 12
const granted = hasBluetoothPermission();

// Shows the system permission dialog if needed (no-op if already granted,
// or not required on this Android version)
const result = await requestBluetoothPermission();

API Reference

Permissions

hasBluetoothPermission(): boolean

Whether BLUETOOTH_CONNECT specifically is already granted (always true below Android 12) — the permission that actually gates connect/print.

requestBluetoothPermission(): Promise<boolean>

Shows the system permission dialog(s) for whatever's needed on this Android version — BLUETOOTH_CONNECT (12+) and POST_NOTIFICATIONS (13+, for the persistent-connection notification's visibility) — and resolves based on BLUETOOTH_CONNECT's result specifically. A denied POST_NOTIFICATIONS alone doesn't make this resolve false: printing still works, the notification just won't show.

Every function that takes data (anything beyond a bare callback) takes a single params object instead of positional arguments, so new fields can be added later without breaking existing call sites.

Connection

getBondedBluetoothPrinters(): BluetoothPrinterDevice[]

Lists Bluetooth devices already paired with the phone via Android's own Bluetooth settings.

connectPrinter(params: ConnectPrinterParams): Promise<boolean>

Opens an RFCOMM/SPP connection to the paired printer. Closes any existing connection first, and remembers the address for auto-reconnect on the next app launch.

disconnectPrinter(): Promise<void>

Closes the current connection and forgets it for auto-reconnect.

isConnectedPrinter(): Promise<boolean>

Whether a printer connection is currently open.

getConnectedPrinter(): Promise<BluetoothPrinterDevice | null>

The currently connected printer, if any.

Printing

printText(params: PrintTextParams): Promise<void>

Prints raw text using the printer's built-in font. ASCII only — use printHtml() for Bangla or other non-Latin scripts.

printImage(params: PrintImageParams): Promise<void>

Prints an image file as a dithered ESC/POS raster image. printerWidthDots: 384 for 58mm printers, 576 for 80mm printers (default 384).

printImageBase64(params: PrintImageBase64Params): Promise<void>

Same as above, from a base64-encoded image string.

pdfToImage(params: PdfToImageParams): Promise<string>

Renders one PDF page to an image file and returns its path.

printPdf(params: PrintPdfParams): Promise<void>

pdfToImage + print, in one call.

htmlToPdf(params: HtmlToPdfParams): Promise<string | null>

Renders HTML to a PDF file using an off-screen WebView and returns its path, or null on failure. pageWidthDp controls how large the content renders (like a CSS viewport width), independent of the final printed width. Leave heightDp unset to auto-measure the real content height (recommended).

printHtml(params: PrintHtmlParams): Promise<boolean>

Full pipeline: htmlToPdf → printPdf. This is how you print Bangla (or other non-Latin) text or any real HTML/CSS layout. Retries once (reconnect + resend) if the underlying write fails, e.g. from a "Broken pipe" when a cheap board drops the link mid-print.

Type Definitions

type BluetoothPrinterDevice = {
  name: string | null;
  address: string;
};

type PrinterImageType = 'PNG' | 'JPEG';

type ConnectPrinterParams = { address: string };

type PrintTextParams = { text: string; feedLines?: number };

type PrintImageParams = {
  imagePath: string;
  printerWidthDots?: number;
  feedLines?: number;
  bandHeightDots?: number; // default 16 - lower for printers that drop/garble large images
  bandDelayMs?: number; // default 60 - raise for printers that drop/garble large images
};

type PrintImageBase64Params = {
  base64: string;
  printerWidthDots?: number;
  feedLines?: number;
  bandHeightDots?: number;
  bandDelayMs?: number;
};

type PdfToImageParams = {
  pdfPath: string;
  imageType?: PrinterImageType;
  page?: number;
  targetWidthPx?: number;
};

type PrintPdfParams = {
  pdfPath: string;
  printerWidthDots?: number;
  page?: number;
  feedLines?: number;
  bandHeightDots?: number;
  bandDelayMs?: number;
};

type HtmlToPdfParams = {
  html: string;
  pageWidthDp?: number;
  heightDp?: number;
  minPageHeightDp?: number;
};

type PrintHtmlParams = {
  html: string;
  printerWidthDots?: number;
  pageWidthDp?: number;
  heightDp?: number;
  minPageHeightDp?: number;
  bandHeightDots?: number;
  bandDelayMs?: number;
};

Persistent connection & auto-reconnect

Connecting through this library keeps the printer connected even if the app is swiped away from Recents — the native side runs a foreground service that outlives the Activity/JS runtime. Every successful connectPrinter() call also remembers the device, so the next time the app is opened (even after being fully killed) it reconnects automatically without the user having to pick the printer again.

connectPrinter() falls back to a direct RFCOMM channel if the standard SDP-based socket fails (common on printers with a broken SDP record), and isConnectedPrinter() reflects a real physical disconnect immediately (via Android's ACL-disconnect broadcast) instead of a stale flag that stays true after the printer silently drops the link.

Printing Bangla / other non-Latin text

ESC/POS printer firmware fonts only cover ASCII, so printText() can't render Bangla. For anything with non-Latin text, render it as an image instead — build a bitmap yourself and use printImage()/printImageBase64(), or write it as HTML/CSS and call printHtml(), which renders it with a real font via WebView and prints the result as a dithered raster image.

Example Application

See the example directory for a complete React Native application demonstrating permission handling, printer pairing/connection, and every print function above.

cd example
yarn install
yarn android

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Code of Conduct

This project adheres to the Code of Conduct.

License

MIT - See LICENSE file for details.

Support

For issues, questions, or suggestions, please open an issue on GitHub.