codel-printer-kit
v1.0.1
Published
Professional JavaScript printing library for receipt/POS printers (USB, Network, Serial) - ESC/POS compatible
Maintainers
Readme
@codel/printer-kit
Professional JavaScript printing library for receipt/POS printers
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-kitDependencies
The library depends on:
serialport- Serial/COM port communicationusb- 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 BufferMethods:
| 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
- 📖 API Reference - Complete API documentation
- ⚡ Electron Integration - Electron setup guide
- 🚀 Usage Scenarios - Real-world examples
- 💡 Examples - Code examples
🆘 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
