Package Exports
- windows-pdf-printer-native
- windows-pdf-printer-native/lib/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (windows-pdf-printer-native) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Windows PDF Printer Native
A production-ready, cross-platform Node.js library for printing PDF documents with native Windows API integration and CUPS support. Built with Clean Architecture principles for maintainability, extensibility, and testability.
Key Highlights:
- ๐๏ธ Clean Architecture - Separation of concerns, dependency inversion, and SOLID principles
- ๐ฏ Native Windows Printing - Direct integration with Windows Print Spooler API (winspool.drv) via Koffi FFI
- ๐ง Unix/Linux/macOS Support - Seamless CUPS integration
- โ DEVMODE Configuration - Correctly applies all print settings (copies, duplex, paper size, orientation)
- ๐ง Advanced Features - Duplex printing, paper tray selection, color control, print quality settings
- ๐ฆ TypeScript First - Full type safety with comprehensive interfaces
- ๐งช Well-Tested - Comprehensive test suite with 73+ passing tests
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- API Reference
- Platform Support
- Examples
- Troubleshooting
- Contributing
- Changelog
- License
Features
๐๏ธ Architecture & Code Quality
โ
Clean Architecture - Organized in layers (core, adapters, services, factories) for maintainability
โ
SOLID Principles - Single Responsibility, Dependency Inversion, Open/Closed
โ
TypeScript First - Full type safety with comprehensive interfaces and type definitions
โ
Testable Design - Easy to mock and test with interface-based architecture
โ
Modern Node.js - Built for Node.js 22+ with native ES modules and TypeScript support
๐จ๏ธ Printing Capabilities
โ
Cross-Platform - Windows, Linux, and macOS with platform-specific optimizations
โ
Native Windows API - Direct winspool.drv integration via Koffi FFI (no spawning processes)
โ
CUPS Integration - Reliable Unix/Linux/macOS printing via CUPS lp command
โ
DEVMODE Configuration - Correctly applies all Windows print settings (fixed in v1.0.1)
โ
Duplex Printing - Full support for simplex, horizontal (short-edge), and vertical (long-edge) duplex
โ
Paper Configuration - Multiple paper sizes (A3, A4, Letter, Legal, Tabloid, custom sizes)
โ
Tray Selection - Choose specific paper trays/sources (Windows: upper, lower, manual feed, etc.)
โ
Color Control - Switch between color and monochrome printing modes
โ
Print Quality - High, medium, low, draft quality settings (Windows)
โ
Multiple Copies - Print 1-9999 copies with collation support
โ
Raw Data Printing - Send PCL, PostScript, ZPL, or raw data directly to printer
๐ Printer Management
โ
List Printers - Enumerate all available system printers with detailed information
โ
Default Printer - Get and use system default printer (fixed GetDefaultPrinterW API)
โ
Printer Capabilities - Query duplex support, color support, available paper sizes/trays
โ
Printer Status - Check printer online status, job queue, and driver information
Recent Improvements (v1.0.1)
๐ง Critical Fixes
DEVMODE Configuration (Windows)
- โ Fixed DEVMODE not being applied to print jobs
- โ Now correctly passes DEVMODE via PRINTER_DEFAULTS when opening printer with OpenPrinterW
- โ Print settings (copies, duplex, paper size, orientation, color) are now properly applied
- โ
Added getAndConfigureDevMode() method that:
- Gets printer's default DEVMODE via DocumentPropertiesW
- Modifies it with user-provided options
- Validates changes with printer driver
- Opens printer with configured DEVMODE
Default Printer Detection (Windows)
- โ Fixed GetDefaultPrinterW API signature (changed from array to pointer)
- โ Now correctly returns default printer name
- โ Proper UTF-16 buffer allocation and decoding
Architecture Improvements
- โ Refactored to Clean Architecture with clear separation of concerns
- โ Created core layer with platform-agnostic types and interfaces
- โ Created adapters layer for Windows-specific implementations
- โ Added services layer for platform detection
- โ Implemented factory pattern for creating platform-specific instances
- โ 100% backward compatible - existing code continues to work
๐งช Testing & Verification
New Testing Tools
- โ
inspect-devmode.ts- Inspect DEVMODE settings directly from printer - โ
test-devmode.ts- Test DEVMODE application with various configurations - โ
monitor-spooler.ts- Monitor print spooler and verify job submission - โ Comprehensive testing guide in TESTING-DEVMODE.md
- โ Clean Architecture documentation in CLEAN-ARCHITECTURE.md
Requirements
All Platforms
- Node.js 22.0.0 or higher (with native TypeScript support)
Windows
- Windows 7 or later
winspool.drv(included with Windows)koffipackage (installed automatically)
Linux/macOS
- CUPS (Common Unix Printing System) - usually pre-installed
lpcommand-line tool- System printer drivers configured via CUPS
Installation
npm install node-pdf-printerOr install dependencies in this repo:
npm installQuick Start
Basic Usage (Facade API - Recommended)
import { PDFPrinter, PrinterManager, getPlatform } from 'node-pdf-printer';
// Check platform
console.log('Platform:', getPlatform()); // 'windows' or 'unix'
// List available printers
const printers = await PrinterManager.getAvailablePrinters();
console.log('Available printers:', printers);
// Get default printer
const defaultPrinter = await PrinterManager.getDefaultPrinter();
console.log('Default printer:', defaultPrinter);
// Create printer instance (uses default printer)
const printer = new PDFPrinter();
// Print a PDF with default settings
await printer.print('./document.pdf');
// Print with advanced options
await printer.print('./document.pdf', {
copies: 2,
duplex: 'vertical', // Long-edge binding (like a book)
paperSize: 9, // PAPER_A4 (Windows) or 'a4' (Unix)
orientation: 'portrait',
color: true,
quality: -4, // PRINT_QUALITY_HIGH (Windows only)
collate: true // Collate copies
});
// Print to specific printer
const hpPrinter = new PDFPrinter('HP LaserJet Pro');
await hpPrinter.print('./invoice.pdf', { copies: 3 });Using Factory Pattern (Clean Architecture API)
import { PrinterFactory, type IPrinter, type IPrinterManager } from 'node-pdf-printer';
// Create platform-specific printer instance
const printer: IPrinter = PrinterFactory.createPrinter();
await printer.print('./document.pdf', { copies: 2 });
// Create platform-specific printer manager
const manager: IPrinterManager = PrinterFactory.createPrinterManager();
const printers = await manager.getAvailablePrinters();
const defaultPrinter = await manager.getDefaultPrinter();Platform-Specific Examples
Windows:
import { PDFPrinter, PAPER_A4, DUPLEX_VERTICAL, PRINT_QUALITY_HIGH } from 'node-pdf-printer';
const printer = new PDFPrinter();
await printer.print('./document.pdf', {
copies: 2,
duplex: 'vertical', // Use DUPLEX_VERTICAL constant or string
paperSize: PAPER_A4, // Use constant or numeric value (9)
paperSource: 2, // Lower tray
quality: PRINT_QUALITY_HIGH, // High quality printing
color: true,
collate: true
});Unix/Linux/macOS:
import { PDFPrinter } from 'node-pdf-printer';
const printer = new PDFPrinter();
await printer.print('./document.pdf', {
copies: 2,
duplex: 'vertical', // CUPS: two-sided-long-edge
paperSize: 'a4', // CUPS paper size string
orientation: 'portrait',
color: true
});API Reference
Classes
PDFPrinter
Main class for printing PDF documents.
Constructor:
new PDFPrinter(printerName?: string)printerName(optional): Specific printer to use. If not provided, uses system default.
Methods:
print(pdfPath: string, options?: PrintOptions): Promise<void>
Print a PDF file with specified options.
await printer.print('./report.pdf', {
copies: 3,
duplex: 'vertical',
paperSize: PAPER_A4,
orientation: 'portrait',
color: true,
paperSource: 1
});printRaw(data: Buffer, documentName?: string, options?: PrintOptions): Promise<void>
Print raw data (PCL, PostScript, etc.) directly to printer.
const rawData = Buffer.from('...');
await printer.printRaw(rawData, 'My Document', {
paperSize: PAPER_LETTER
});getPrinterName(): string
Get the name of the printer being used.
getCapabilities(): PrinterCapabilities | null
Get printer capabilities (duplex support, color support, etc.).
PrinterManager
Static class for managing printers.
Static Methods:
getAvailablePrinters(): PrinterInfo[]
Get list of all available printers.
const printers = PrinterManager.getAvailablePrinters();getDefaultPrinter(): string | null
Get the system default printer name.
printerExists(printerName: string): boolean
Check if a printer exists.
getPrinterCapabilities(printerName: string): PrinterCapabilities | null
Get capabilities for a specific printer.
Interfaces
PrintOptions
interface PrintOptions {
printer?: string; // Printer name
copies?: number; // Number of copies (default: 1)
duplex?: 'simplex' | 'horizontal' | 'vertical';
paperSize?: number; // Paper size constant
paperSource?: number; // Paper tray/source
orientation?: 'portrait' | 'landscape';
color?: boolean; // true = color, false = monochrome
quality?: number; // Print quality
collate?: boolean; // Collate copies
}Print Options Explained:
copies: Number of copies to print (1-9999). Default: 1duplex: Duplex (double-sided) printing mode'simplex'- Single-sided printing (one side of paper)'horizontal'- Flip on short edge (like a notepad)'vertical'- Flip on long edge (like a book)
paperSize: Paper size to use- Windows: Numeric constant (e.g.,
9for A4,1for Letter) - Unix: String format (e.g.,
'a4','letter','legal') - See Paper Sizes constants below
- Windows: Numeric constant (e.g.,
paperSource: Paper tray/source (Windows only)1- Upper tray2- Lower tray3- Middle tray4- Manual feed7- Auto select- Exact values depend on printer model
orientation: Page orientation'portrait'- Vertical orientation (default)'landscape'- Horizontal orientation (90ยฐ rotation)
color: Color printing modetrue- Color printing (if printer supports)false- Monochrome/grayscale printing
quality: Print quality level (Windows only)-4- High quality (slower, more ink)-3- Medium quality-2- Low quality-1- Draft quality (faster, less ink)
collate: Collation for multiple copiestrue- Print complete sets (Page 1,2,3... Page 1,2,3... Page 1,2,3...)false- Print all of each page (Page 1,1,1... Page 2,2,2... Page 3,3,3...)- Only matters when
copies > 1and document has multiple pages - Example: 3 copies of a 5-page document
- Collated: โ โกโขโฃโค โ โกโขโฃโค โ โกโขโฃโค (ready to distribute)
- Not collated: โ โ โ โกโกโก โขโขโข โฃโฃโฃ โคโคโค (for manual assembly)
PrinterInfo
interface PrinterInfo {
name: string;
serverName?: string;
portName?: string;
driverName?: string;
location?: string;
comment?: string;
status: number;
isDefault?: boolean;
}PrinterCapabilities
interface PrinterCapabilities {
supportsDuplex: boolean;
supportsColor: boolean;
defaultPaperSize: number;
availablePaperSizes: number[];
availablePaperSources: number[];
}Constants
Paper Sizes
PAPER_LETTER(1) - 8.5" x 11"PAPER_LEGAL(5) - 8.5" x 14"PAPER_A4(9) - 210mm x 297mmPAPER_A3(8) - 297mm x 420mmPAPER_TABLOID(3) - 11" x 17"
Duplex Modes
DUPLEX_SIMPLEX(1) - Single-sidedDUPLEX_HORIZONTAL(2) - Flip on short edgeDUPLEX_VERTICAL(3) - Flip on long edge
Orientation
PORTRAIT(1)LANDSCAPE(2)
Color Modes
MONOCHROME(1)COLOR(2)
Print Quality
PRINT_QUALITY_HIGH(-4)PRINT_QUALITY_MEDIUM(-3)PRINT_QUALITY_LOW(-2)PRINT_QUALITY_DRAFT(-1)
Examples
Simple Print
import { PDFPrinter } from 'node-pdf-printer';
const printer = new PDFPrinter();
await printer.print('./document.pdf');Duplex Printing
import { PDFPrinter, PAPER_A4 } from 'node-pdf-printer';
const printer = new PDFPrinter();
// Vertical duplex (flip on long edge)
await printer.print('./document.pdf', {
duplex: 'vertical',
paperSize: PAPER_A4
});Print to Specific Printer
import { PDFPrinter } from 'node-pdf-printer';
const printer = new PDFPrinter('HP LaserJet Pro');
await printer.print('./document.pdf', {
copies: 5,
collate: true
});Advanced Configuration
import { PDFPrinter, PAPER_A4, PRINT_QUALITY_HIGH } from 'node-pdf-printer';
const printer = new PDFPrinter();
await printer.print('./document.pdf', {
copies: 3,
duplex: 'vertical',
paperSize: PAPER_A4,
paperSource: 2, // Lower tray
orientation: 'portrait',
color: true,
quality: PRINT_QUALITY_HIGH,
collate: true
});List All Printers
import { listPrinters, PrinterManager } from 'node-pdf-printer';
const printers = listPrinters();
printers.forEach(printer => {
console.log(`${printer.name}${printer.isDefault ? ' (DEFAULT)' : ''}`);
const capabilities = PrinterManager.getPrinterCapabilities(printer.name);
if (capabilities) {
console.log(` Duplex: ${capabilities.supportsDuplex}`);
console.log(` Color: ${capabilities.supportsColor}`);
}
});Running Examples
# List all printers
node --experimental-strip-types examples/list-printers.ts
# Simple print
node --experimental-strip-types examples/simple-print.ts
# Duplex printing
node --experimental-strip-types examples/duplex-print.ts
# Advanced printing
node --experimental-strip-types examples/advanced-print.tsOr use npm scripts:
npm run example:simple
npm run example:duplex
npm run example:advanced
# Test DEVMODE configuration
npm run example:test-devmode
npm run example:monitorTesting DEVMODE Configuration
To verify that print options (copies, duplex, paper size, etc.) are being applied correctly, see the comprehensive guide: TESTING-DEVMODE.md
Quick test:
# Inspect DEVMODE settings directly โญ RECOMMENDED
npm run example:inspect-devmode
# Test with Microsoft Print to PDF
npm run example:test-devmode
# Monitor print spooler with detailed instructions
npm run example:monitorVerification methods:
- โญ DEVMODE Inspector -
npm run example:inspect-devmode- See all DEVMODE fields directly - Windows Print Queue - View job properties in the print queue
- PowerShell -
Get-PrintJobshows basic job info (โ ๏ธ NOT DEVMODE settings) - Process Monitor - Use Sysinternals Process Monitor to see API calls
- Event Viewer - Check Windows event logs for print job details
Important: PowerShell's Get-PrintJob does NOT show DEVMODE settings (duplex, paper size, orientation, etc.). Use our inspector tool instead!
See TESTING-DEVMODE.md for detailed instructions on each method.
Troubleshooting
Common Issues
"Printer not found" error
Make sure the printer name is correct. Use listPrinters() to see all available printers:
import { listPrinters } from 'node-pdf-printer';
const printers = await listPrinters(); // Note: async on Unix
console.log(printers);"Failed to start print job" error (Windows)
- Verify the printer is online and not paused
- Check you have sufficient permissions to print
- Ensure the printer driver is properly installed
- Try printing a test page from Windows Settings to confirm functionality
- Check Windows Event Viewer for detailed error messages
"lp: command not found" (Unix/Linux)
Install CUPS:
# Ubuntu/Debian
sudo apt-get install cups
# Fedora/RHEL
sudo yum install cups
# macOS (usually pre-installed)
brew install cupsDuplex not working
Not all printers support duplex printing. Check capabilities:
const printer = new PDFPrinter();
const capabilities = await printer.getCapabilities();
console.log('Duplex supported:', capabilities?.supportsDuplex);On Unix systems, verify CUPS configuration:
lpoptions -p YourPrinterName -l | grep DuplexPDF not rendering correctly
This library sends raw PDF data to the printer:
- Windows: Ensure your printer supports PDF direct printing (PostScript/PCL)
- Unix: CUPS handles PDF conversion automatically if drivers are installed
- Verify the PDF file is valid and not corrupted
- For complex PDFs with advanced features, consider pre-processing
- Test with a simple single-page PDF first
Permission denied errors (Unix)
Add your user to the lp or lpadmin group:
sudo usermod -a -G lp $USER
# Log out and back in for changes to take effectPlatform-Specific Notes
Windows
- Requires the printer to be installed and configured in Windows
- Driver-specific features may vary between printer models
- Some printers may require specific data formats (RAW vs. PostScript)
Linux
- Ensure CUPS service is running:
systemctl status cups - Configure printers via CUPS web interface:
http://localhost:631 - Some features depend on PPD (PostScript Printer Description) files
macOS
- CUPS is pre-installed but may need to be started
- Use System Preferences โ Printers & Scanners to configure printers
- Some features require specific printer drivers from manufacturer
Platform Support
This library supports Windows, Linux, and macOS with platform-specific optimizations:
Windows Implementation
- Technology: Native
winspool.drvAPI via Koffi FFI - Performance: Synchronous operations for immediate feedback
- Capabilities: Full control over all printer settings
- Advanced Features: Paper source/tray selection, print quality settings, detailed printer info
Unix/Linux/macOS Implementation
- Technology: CUPS
lpcommand-line interface - Performance: Asynchronous operations for non-blocking execution
- Capabilities: Standard CUPS-supported features
- Requirements: CUPS installed (pre-installed on most systems)
Feature Comparison Matrix
| Feature | Windows | Unix/Linux/macOS | Notes |
|---|---|---|---|
| Printer Discovery | โ Sync | โ Async | List all available printers |
| Default Printer | โ Sync | โ Async | Get system default printer |
| Duplex Printing | โ | โ | One-sided, long-edge, short-edge |
| Paper Size | โ Numeric | โ String | Windows: 9 (A4), Unix: 'a4' |
| Paper Source/Tray | โ | โ | Windows-only feature |
| Print Quality | โ | โ | Windows-only feature |
| Color Mode | โ | โ | Color or monochrome |
| Orientation | โ | โ | Portrait or landscape |
| Multiple Copies | โ | โ | With collation support |
| Printer Capabilities | โ | Limited | Detailed info on Windows |
How It Works
Windows
Uses Koffi to interface directly with Windows Print Spooler API (winspool.drv):
- OpenPrinterW - Opens a handle to the printer
- StartDocPrinterW - Starts a print job with DOC_INFO_1W structure
- StartPagePrinter - Begins a new page
- WritePrinter - Sends raw PDF data to the printer
- EndPagePrinter - Ends the current page
- EndDocPrinter - Completes the print job
- ClosePrinter - Closes the printer handle
Configuration is passed via DEVMODE structures to control duplex, paper size, orientation, etc.
Unix/Linux/macOS
Uses CUPS command-line interface:
- Constructs
lpcommand with appropriate flags - Passes options like
-o sides=two-sided-long-edgefor duplex - Executes command via Node.js
child_process - Captures output and job IDs for tracking
Testing
This library includes a comprehensive test suite covering all major functionality:
Running Tests
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage report
npm run test:coverage
# Run tests with verbose output
npm run test:verboseTest Coverage
The test suite includes:
- Windows API Tests: Validates Koffi bindings, structures, and constants
- PrinterManager Tests: Tests printer discovery, default printer, and capabilities
- PDFPrinter Tests: Tests printing functionality with various options
- Unix Printer Tests: Tests CUPS integration (skipped on Windows)
- Cross-Platform Tests: Tests unified API and platform detection
Tests are automatically skipped on platforms where they don't apply (e.g., Unix tests skip on Windows).
Test Results
Test Suites: 4 passed (1 skipped on non-Unix)
Tests: 73 passed, 17 skipped
Coverage: Comprehensive coverage of all public APIsContributing
Contributions are welcome! Please read our Contributing Guide for details on:
- Development setup
- Code style guidelines
- Testing requirements
- Submitting pull requests
Changelog
See CHANGELOG.md for a list of changes in each version.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- ๐ Documentation: Full API reference available in this README
- ๐ Bug Reports: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ง Email: your.email@example.com
Acknowledgments
- Built with Koffi for native Windows API integration
- CUPS (Common Unix Printing System) for Unix/Linux/macOS support
- Inspired by the Node.js printing community
Related Projects
- node-printer - Alternative native printer binding
- pdf-to-printer - Windows-only PDF printing
- unix-print - Unix-focused printing library
Created with โค๏ธ for the Node.js community