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

detonger-web-bt

v1.0.2

Published

Independently developed library for connecting to DothanTech Bluetooth printers using Web Bluetooth API.

Readme

[!IMPORTANT] This is NOT an official DothanTech library. I am not affiliated with DothanTech in any way and take no responsibility for the use of this library.

DETONGER WEB BT

JavaScript/TypeScript library for DothanTech/LPAPI-BLE thermal printers via Web Bluetooth API, with optional React integration.

Live Demo

Live Demo

Tested with

  • DP30S

Installation

npm install detonger-web-bt

React 18+ is optional — required only when using the React integration (detonger-web-bt/react). The core library works without React.


Quick Start (Core)

import { DothanTechPrinter } from 'detonger-web-bt';

const printer = new DothanTechPrinter({ namePrefix: "DP30S-", paperWidth: 56 });

await printer.connect();
await printer.printText('Hello World!', { fontSize: 24, textAlign: 'center' });
await printer.feedLines(3);
await printer.disconnect();

See the vanilla JS integration docs and the HTML demo for a full working example with no build step.

Quick Start (React)

import { PrinterProvider, usePrinter, usePrinterConnection } from 'detonger-web-bt/react';

function App() {
  return (
    <PrinterProvider config={{ namePrefix: "DP30S-", paperWidth: 56 }}>
      <PrintButton />
    </PrinterProvider>
  );
}

function PrintButton() {
  const { printText, isConnected } = usePrinter();
  const { connect, isConnecting } = usePrinterConnection();

  if (!isConnected) {
    return (
      <button onClick={connect} disabled={isConnecting}>
        {isConnecting ? 'Connecting...' : 'Connect'}
      </button>
    );
  }

  return <button onClick={() => printText('Hello World!')}>Print</button>;
}

API Reference

new DothanTechPrinter(config?)

| Option | Type | Default | Description | |--------|------|---------|-------------| | namePrefix | string | 'DP' | Device name prefix for Bluetooth filtering | | paperWidth | number | 56 | Paper width in mm (fallback for maxWidth) | | mtu | number | 512 | Max packet MTU size | | packetDelay | number | 10 | Delay between packets (ms) | | debug | boolean | false | Enable verbose console logging | | serviceUUID | string | '0000ff00-...' | Bluetooth service UUID | | writeUUID | string | '0000ff02-...' | Write characteristic UUID | | notifyUUID | string | '0000ff01-...' | Notify characteristic UUID |

Connection

| Signature | Description | |-----------|-------------| | connect(): Promise<void> | Connect to printer via Bluetooth | | disconnect(): Promise<void> | Disconnect from printer | | isConnected(): boolean | true if connected or printing | | getStatus(): ConnectionStatus | Current connection status | | getDeviceName(): string \| null | Connected device name or null |

Printing

| Signature | Description | |-----------|-------------| | printText(text, options?): Promise<PrintStats> | Print text with formatting | | printImage(imageUrl, options?): Promise<PrintStats> | Print image from URL | | printCanvas(canvas, options?): Promise<PrintStats> | Print a canvas element | | printImageData(imageData, options?): Promise<PrintStats> | Print raw ImageData | | feedLines(n): Promise<void> | Feed N blank lines (0–255) |

Printer Status

| Signature | Description | |-----------|-------------| | refreshPrinterStatus(options?): Promise<void> | Query printer params. { minimal: true } for faster UI-only refresh | | getPrinterStatus(): PrinterStatus | Latest printer status (DPI, paper width, density, etc.) | | getPrintingStats(): PrinterPrintStats | Cumulative print statistics | | getPaperWidth(): number | Current paper width in mm | | setPaperWidth(width): void | Set paper width in mm (≥ 1) |

Event Callbacks

| Signature | Description | |-----------|-------------| | onStatusChange(cb): () => void | Called on connection status change. Returns unsubscribe fn | | onDataReceived(cb): () => void | Called on incoming data. Returns unsubscribe fn | | onError(cb): () => void | Called on error. Returns unsubscribe fn |


Types

TextPrintOptions

| Option | Type | Description | |--------|------|-------------| | fontSize | number | Font size in pixels | | fontFamily | string | Font family name | | fontWeight | 'normal' \| 'bold' | Font weight | | fontStyle | 'normal' \| 'italic' | Font style | | textAlign | 'left' \| 'center' \| 'right' | Text alignment | | lineHeight | number | Line spacing multiplier | | padding | [number, number, number, number] | Margins [top, right, bottom, left] in mm | | maxWidth | number | Max width in mm | | autoScale | boolean | Auto-scale to fit max width | | minScale | number | Minimum scale factor (e.g. 0.3 = 30%) | | autoWrap | boolean | Auto line wrapping |

ImagePrintOptions

| Option | Type | Description | |--------|------|-------------| | threshold | number | Binarization threshold 0–255 | | invertColors | boolean | Invert colors | | scale | number | Scale factor | | autoCrop | boolean | Auto-crop white margins | | maxWidth | number | Max width in mm | | ditherMethod | 'atkinson' \| 'threshold' \| 'none' | Dithering algorithm |

PrintStats

Returned by all print methods.

| Property | Type | Description | |----------|------|-------------| | totalBytes | number | Total bytes sent | | bitmapLines | number | Number of bitmap lines | | commandsCount | number | Number of print commands | | compressionRatio | number | Compression ratio (%) | | conversionTime | number | Image conversion time (ms) | | transmissionTime | number | Transmission time (ms) | | transmissionSpeed | number | Transmission speed (KB/s) |

PrinterStatus

Returned by getPrinterStatus().

| Property | Type | Description | |----------|------|-------------| | deviceName | string | Device name | | deviceVersion | string | Hardware version | | softwareVersion | string | Software version | | manufacturer | string | Manufacturer | | printerDPI | number | DPI | | printerWidth | number | Width in pixels | | paperWidthMm | number | Paper width in mm | | currentDensity | number | Print density | | currentDensityLevel | number | Density level | | currentSpeed | number | Print speed | | currentSpeedLevel | number | Speed level | | currentPaperType | PaperType | Current paper type |

PrinterPrintStats

Returned by getPrintingStats().

| Property | Type | Description | |----------|------|-------------| | workLines | number | Total work lines | | printLines | number | Total printed lines | | nullLines | number | Blank lines | | printPages | number | Total printed pages |

PaperType

| Constant | Description | |----------|-------------| | PaperType.Ticket | Receipt paper | | PaperType.Adhesive | Sticker/label paper | | PaperType.CardPaper | Cardboard paper | | PaperType.Transparent | Transparent film |

ConnectionStatus

'disconnected' | 'connecting' | 'connected' | 'printing' | 'error'

Callback Types

| Type | Signature | |------|-----------| | StatusChangeCallback | (status: ConnectionStatus) => void | | DataReceivedCallback | (data: Uint8Array) => void | | ErrorCallback | (error: Error) => void |


React API

<PrinterProvider>

| Prop | Type | Default | Description | |------|------|---------|-------------| | config | PrinterConfig | {} | Printer configuration | | autoConnect | boolean | false | Auto-connect on mount | | autoDisconnectOnUnmount | boolean | true | Auto-disconnect on unmount | | onConnected | () => void | — | Called on successful connection | | onDisconnected | () => void | — | Called on disconnection | | onError | (error: Error) => void | — | Called on error |

usePrinter()

Core access to the printer. Must be inside <PrinterProvider>.

const {
  printer,           // DothanTechPrinter instance
  isConnected,       // boolean
  connectionStatus,  // ConnectionStatus
  deviceName,        // string | null
  printerStatus,     // PrinterStatus | null
  printerStats,      // PrinterPrintStats | null
  connect,           // () => Promise<void>
  disconnect,        // () => Promise<void>
  refreshStatus,     // (options?: { full?: boolean }) => Promise<void>
  printText,         // (text, options?) => Promise<PrintStats>
  printImage,        // (imageUrl, options?) => Promise<PrintStats>
  printCanvas,       // (canvas, options?) => Promise<PrintStats>
  printImageData,    // (imageData, options?) => Promise<PrintStats>
  feedLines,         // (n) => Promise<void>
  onError,           // (cb) => () => void
  onStatusChange,    // (cb) => () => void
} = usePrinter();

usePrinterConnection()

Connection management with loading and error states.

const {
  connect,           // () => Promise<void>
  disconnect,        // () => Promise<void>
  isConnected,       // boolean
  isConnecting,      // boolean
  isDisconnecting,   // boolean
  connectionStatus,  // ConnectionStatus
  error,             // Error | null
  clearError,        // () => void
} = usePrinterConnection();

usePrinterStatus(options?)

Status monitoring with optional polling.

const {
  status,    // PrinterStatus | null
  stats,     // PrinterPrintStats | null
  isLoading, // boolean
  refresh,   // (full?: boolean) => Promise<void>
} = usePrinterStatus({
  refetchInterval: 5000, // polling interval in ms, or false to disable
  enabled: true,
});

Troubleshooting

  • Won't connect: Requires Chrome or Edge (Web Bluetooth API). Printer must be on and in pairing mode.
  • "usePrinter must be used within a PrinterProvider": Hook must be inside <PrinterProvider>.
  • Printing fails: Check isConnected is true. Enable debug: true in config for console logs.

License

MIT