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 🙏

© 2025 – Pkg Stats / Ryan Hefner

codel-printer-kit

v1.0.1

Published

Professional JavaScript printing library for receipt/POS printers (USB, Network, Serial) - ESC/POS compatible

Readme

@codel/printer-kit

Professional JavaScript printing library for receipt/POS printers

npm version License: MIT Node.js

Enterprise-ready printing solution for thermal receipt printers supporting USB, Network (RAW), and Serial connections with full ESC/POS command support.

✨ Features

  • 🖨️ Multiple Transports: USB, Network (TCP/IP RAW 9100), Serial (COM/TTY)
  • 🔍 Auto-Discovery: Find printers automatically on your network or USB
  • 📄 Fluent Receipt Builder: Intuitive API for building receipts
  • 🎯 ESC/POS Standard: Full support for ESC/POS thermal printers
  • Queue Management: Built-in print job queue with timeout handling
  • 🔧 TypeScript: Full type definitions included
  • 🚀 Electron Ready: Works seamlessly in Electron Main process
  • 📦 Zero Config: Works out of the box with sensible defaults

🎯 Why Main-Process Only?

This library requires native Node.js modules (serialport, usb) that access system hardware directly. This is only possible in:

  • ✅ Node.js applications
  • ✅ Electron Main process
  • ❌ ~~Browser/Renderer process~~ (use IPC bridge)
  • ❌ ~~Web Workers~~ (no hardware access)

For Electron apps, see Electron Integration Guide.

Features

  • 🔌 Multiple Connection Types: USB, Network (RAW/IPP), Serial (COM)
  • 🖨️ ESC/POS Compatible: Full command set for thermal printers
  • 📄 Receipt Builder: Fluent API for building receipts
  • 🔍 Auto Discovery: Find printers on USB, network (mDNS), or serial ports
  • Job Queue: Prevents print conflicts with async queue management
  • 🎯 Type-Safe: Full TypeScript support
  • 🚀 Production Ready: Error handling, timeouts, and reliability built-in

Installation

npm install @codel/printer-kit

Dependencies

The library depends on:

  • serialport - Serial/COM port communication
  • usb - USB device access

Note: USB printing requires appropriate drivers:

  • Windows: libusb drivers (install via Zadig)
  • Linux: udev rules or sudo permissions
  • macOS: Built-in support (may require permissions)

Quick Start

Basic Usage

import { PrinterManager, ReceiptBuilder, Alignment, BarcodeType } from "@codel/printer-kit";

// Create manager
const manager = new PrinterManager();

// Discover printers
const printers = await manager.discover();
console.log("Found printers:", printers);

// Build receipt
const receipt = new ReceiptBuilder()
  .textLine("RECEIPT", { align: Alignment.CENTER, bold: true, size: { width: 2, height: 2 } })
  .line()
  .separator("=", 32)
  .textLine("Item 1        $10.00")
  .textLine("Item 2        $20.00")
  .separator("-", 32)
  .textLine("TOTAL         $30.00", { bold: true })
  .line(2)
  .barcode("123456789", { type: BarcodeType.CODE128, align: Alignment.CENTER })
  .qrcode("https://example.com", { align: Alignment.CENTER })
  .line()
  .textLine("Thank you!", { align: Alignment.CENTER })
  .cut();

// Print
const result = await manager.print(printers[0].ref, receipt);
console.log("Print result:", result);

API Reference

PrinterManager

Main interface for printer operations.

discover(options?: DiscoveryOptions): Promise<DiscoveredPrinter[]>

Discover available printers.

// Discover all printers
const all = await manager.discover();

// Discover only network printers
const network = await manager.discover({
  types: [PrinterType.NETWORK],
  network: {
    subnet: "192.168.1.0/24",
    ports: [9100],
    mdns: true
  }
});

// Discover USB printers with specific vendor IDs
const usb = await manager.discover({
  types: [PrinterType.USB],
  usb: {
    vendorIds: [0x04b8] // Epson
  }
});

// Discover serial printers
const serial = await manager.discover({
  types: [PrinterType.SERIAL]
});

DiscoveryOptions:

| Property | Type | Description | | ----------------- | --------------- | ------------------------------------------------- | | types | PrinterType[] | Filter by printer types (USB, NETWORK, SERIAL) | | timeout | number | Discovery timeout in milliseconds (default: 3000) | | network.subnet | string | Subnet to scan (e.g., "192.168.1.0/24") | | network.ports | number[] | Ports to test (default: [9100]) | | network.mdns | boolean | Enable mDNS discovery (default: true) | | usb.vendorIds | number[] | Filter by USB vendor IDs | | serial.baudRate | number | Default baud rate for testing |

print(printerRef: PrinterRef, data: Buffer | ReceiptBuilder, options?: PrintOptions): Promise<PrintResult>

Send print job to printer.

const result = await manager.print(printer.ref, receipt, {
  timeout: 30000,
  copies: 1
});

PrintOptions:

| Property | Type | Description | | --------- | -------- | ---------------------------------------------- | | timeout | number | Print timeout in milliseconds (default: 30000) | | copies | number | Number of copies (1-100, default: 1) |

PrintResult:

{
  success: boolean;
  jobId: string;
  sentBytes: number;
  duration: number; // milliseconds
  error?: Error;
}

Queue Management

// Get queue size
const queueSize = manager.getQueueSize();

// Get current job
const currentJob = manager.getCurrentJob();

// Clear queue (does not cancel current job)
manager.clearQueue();

ReceiptBuilder

Fluent API for building ESC/POS receipts.

const receipt = new ReceiptBuilder()
  .text("Hello", { bold: true })
  .line()
  .textLine("World", { align: Alignment.CENTER })
  .separator("-", 32)
  .barcode("123456", { type: BarcodeType.CODE128 })
  .qrcode("https://example.com", { size: 6 })
  .image(imageBuffer, 384, 200)
  .cut()
  .drawer()
  .build(); // Returns Buffer

Methods:

| Method | Description | | ----------------------------- | ------------------------ | | text(content, options?) | Add text with formatting | | textLine(content, options?) | Add text + line feed | | line(count?) | Add line feed(s) | | align(alignment) | Set text alignment | | separator(char, width) | Add horizontal line | | barcode(data, options?) | Add barcode | | qrcode(data, options?) | Add QR code | | image(data, width, height) | Add raster image (1-bit) | | cut(partial?) | Cut paper | | drawer(pin?) | Open cash drawer | | raw(buffer) | Add raw ESC/POS command | | build() | Build final Buffer |

PrinterRef Metadata

Each discovered printer has a ref with metadata specific to its type:

USB Metadata

{
  type: PrinterType.USB,
  id: 'usb-1234-5678',
  meta: {
    vendorId: 0x04b8,        // e.g., Epson
    productId: 0x0202,
    manufacturer: 'EPSON',
    product: 'TM-T20',
    serialNumber: 'ABC123'
  }
}

Network Metadata

{
  type: PrinterType.NETWORK,
  id: 'network-192.168.1.100',
  meta: {
    ip: '192.168.1.100',
    port: 9100,
    protocol: 'raw',         // 'raw' or 'ipp'
    hostname: 'printer.local',
    model: 'TM-T88V'
  }
}

Serial Metadata

{
  type: PrinterType.SERIAL,
  id: 'serial-COM3',
  meta: {
    path: 'COM3',            // or '/dev/ttyUSB0' on Linux
    manufacturer: 'FTDI',
    serialNumber: '1234',
    pnpId: 'USB\\VID_04B8...'
  }
}

Using with Electron

This is a library, not an Electron app. You integrate it into your Electron app:

Main Process

// main.js or main.ts
import { app, ipcMain } from "electron";
import { PrinterManager, ReceiptBuilder, Alignment } from "@codel/printer-kit";

const printerManager = new PrinterManager();

// Discover printers
ipcMain.handle("printer:discover", async () => {
  try {
    return await printerManager.discover();
  } catch (error) {
    console.error("Discovery failed:", error);
    throw error;
  }
});

// Print receipt
ipcMain.handle("printer:print", async (event, printerRef, receiptData) => {
  try {
    // Build receipt from data
    const receipt = new ReceiptBuilder()
      .textLine(receiptData.title, { align: Alignment.CENTER, bold: true })
      .line()
      .textLine(`Total: $${receiptData.total}`)
      .cut();

    return await printerManager.print(printerRef, receipt);
  } catch (error) {
    console.error("Print failed:", error);
    throw error;
  }
});

Renderer Process (Vue/React/etc)

// In your Vue component or React app
const printers = await window.electron.ipcRenderer.invoke("printer:discover");

const result = await window.electron.ipcRenderer.invoke("printer:print", printers[0].ref, {
  title: "My Receipt",
  total: 50.0
});

Preload Script

// preload.js
import { contextBridge, ipcRenderer } from "electron";

contextBridge.exposeInMainWorld("electron", {
  ipcRenderer: {
    invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args)
  }
});

Advanced Usage

Custom Transport

import { NetworkTransport } from "@codel/printer-kit";

// Direct transport usage (advanced)
const transport = new NetworkTransport({
  ip: "192.168.1.100",
  port: 9100,
  protocol: "raw"
});

await transport.connect();
await transport.send(buffer);
await transport.disconnect();

Serial Port Configuration

import { SerialTransport } from "@codel/printer-kit";

const transport = new SerialTransport(
  { path: "COM3" },
  {
    baudRate: 9600,
    dataBits: 8,
    stopBits: 1,
    parity: "none"
  }
);

Raw ESC/POS Commands

const receipt = new ReceiptBuilder()
  .raw(Buffer.from([0x1b, 0x40])) // ESC @ (initialize)
  .raw(Buffer.from([0x1b, 0x61, 0x01])) // ESC a 1 (center align)
  .text("Centered")
  .build();

Error Handling

The library provides specific error types:

import { PrinterKitError, DiscoveryError, TransportError, TimeoutError, InvalidConfigError, PrintJobError } from "@codel/printer-kit";

try {
  await manager.print(printer.ref, receipt);
} catch (error) {
  if (error instanceof TimeoutError) {
    console.error("Print timeout");
  } else if (error instanceof TransportError) {
    console.error("Connection failed:", error.cause);
  } else if (error instanceof PrintJobError) {
    console.error("Print job failed:", error.message);
  }
}

Known Limitations

USB

  • Requires driver installation on Windows (libusb via Zadig)
  • May require root/sudo on Linux
  • Some printers use proprietary protocols
  • Direct USB printing bypasses system spooler (no print queue visibility)

Network

  • IPP support is placeholder (use RAW for now)
  • mDNS discovery is basic implementation
  • Firewall may block discovery
  • Only /24 subnets supported in scanning

Serial

  • Requires correct baud rate configuration
  • No auto-detection of serial printers (lists all COM ports)
  • Driver must be installed for USB-to-Serial adapters

Common Vendor IDs

| Brand | Vendor ID | Common Models | | -------------- | --------- | --------------------- | | Epson | 0x04b8 | TM-T20, TM-T88 series | | Star Micronics | 0x0519 | TSP100, TSP650 | | Bixolon | 0x1504 | SRP-350, SRP-275 | | Citizen | 0x1CB0 | CT-S310, CT-S601 |

ESC/POS Command Reference

Commonly used commands available through ReceiptBuilder:

🛣️ Roadmap

Version 1.1 (Planned)

  • 🔹 printFromJson(template) - JSON-based receipt templates
  • 🔹 Printer Profiles (Epson, Star, Bixolon presets)
  • 🔹 Image raster optimization
  • 🔹 Retry logic with exponential backoff

Version 1.2 (Planned)

  • 🔹 mDNS discovery improvements
  • 🔹 Custom serial baud rates
  • 🔹 Receipt preview (HTML/Canvas)
  • 🔹 Multi-language support

Version 2.0 (Future)

  • 🔹 IPP protocol support
  • 🔹 Bidirectional communication
  • 🔹 Print status feedback
  • 🔹 Advanced error recovery

📚 Documentation

🆘 Support

  • 📖 Docs: Full documentation available
  • 🐛 Issues: Please report on GitHub
  • 💬 Questions: Check the examples and guides

⭐ Show Your Support

If this library helps your project, please consider:

  • ⭐ Starring the repository
  • 🐛 Reporting bugs
  • 💡 Suggesting features
  • 📖 Improving documentation

Made with ❤️ for the printing community

Status: ✅ Production Ready | API Frozen v1.0.0 | Actively Maintained