Open-source bulk printing for web applications.
PrintBridge enables web applications to print documents directly to local printers without browser dialogs, certificate management, or memory-bloating base64 transfers. Print 100 invoices with one click. Send shipping labels directly to thermal printers. Automate overnight print jobs.
Web applications need to print documents programmatically - shipping labels, invoices, receipts, reports - but browsers have severe limitations:
| Approach | Problems |
|---|---|
| window.print() | Shows dialog every time, no printer selection, no batch support, blocks UI |
| JSPM | Base64 encoding bloats memory (100MB PDF = 133MB in browser), limited error feedback |
| QZ Tray | Requires certificate management, firewall configuration, complex setup |
PrintBridge provides:
- Batch printing - Print hundreds of documents with a single API call
- Zero configuration - Install the agent and go. No certificates, no firewall rules
- Memory efficient - URL passthrough means the browser never loads document content
- Real status feedback - Know exactly what printed, what failed, and why
- Raw printing - Send ESC/POS, ZPL, EPL directly to receipt and label printers
- Configurable error handling - Stop on error, continue anyway, or retry failed jobs
- Open source - MIT licensed, no vendor lock-in
┌─────────────────┐ WebSocket ┌─────────────────┐
│ Your Web App │◀──────────────────▶│ PrintBridge │───▶ Printer
│ + JS SDK │ localhost:9718 │ Agent │
└─────────────────┘ └─────────────────┘
- User installs the lightweight PrintBridge agent (runs in system tray)
- Your web app includes the JavaScript SDK (~8KB gzipped)
- SDK connects to agent via localhost WebSocket (port 9718)
- Send print jobs with document URLs - agent downloads and prints
- Receive real-time status updates
Windows:
# Download installer from GitHub Releases
# https://github.com/mattpilott/PrintBridge/releasesnpm install printbridgeOr via CDN:
<script src="https://unpkg.com/printbridge@latest/dist/printbridge.min.js"></script>import { PrintBridge } from 'printbridge';
const bridge = new PrintBridge();
await bridge.connect();
// Print a single document
const job = await bridge.print({
url: 'https://api.example.com/invoices/12345.pdf',
headers: { 'Authorization': 'Bearer your-token' },
printer: 'HP LaserJet Pro'
});
job.on('completed', () => console.log('Printed!'));
job.on('failed', (err) => console.error('Failed:', err));// Print 100 invoices with progress tracking
const batch = await bridge.printBatch(
invoiceIds.map(id => ({
url: `https://api.example.com/invoices/${id}.pdf`,
headers: { 'Authorization': 'Bearer your-token' },
printer: 'HP LaserJet Pro'
})),
{
onError: 'continue', // Keep printing even if some fail
onProgress: ({ completed, failed, total }) => {
console.log(`Progress: ${completed}/${total}, Failed: ${failed}`);
}
}
);
const results = await batch.wait();
console.log(`Completed: ${results.completed}, Failed: ${results.failed}`);// Browser just sends the URL - agent downloads directly
// No base64 bloat, no memory spikes
await bridge.print({
url: 'https://api.example.com/large-document.pdf',
headers: { 'Authorization': 'Bearer xxx' }
});// Send raw commands to receipt/label printers
await bridge.printRaw({
data: zplLabelCommands,
printer: 'Zebra ZT410',
contentType: 'application/x-zpl'
});const printers = await bridge.getPrinters();
printers.forEach(p => {
console.log(`${p.name} - ${p.status}`);
console.log(` Color: ${p.capabilities.color}`);
});const batch = await bridge.printBatch(documents, {
onError: 'stop', // Stop on first error (default)
onError: 'continue', // Skip failures, continue with rest
onError: 'retry', // Retry failed jobs
maxRetries: 3
});| Platform | Status |
|---|---|
| Windows 10/11 | v1.0 (current focus) |
| macOS | Planned (v1.1) |
| Linux | Planned (v1.2) |
Rendered Documents:
- PDF (via SumatraPDF)
- Images (PNG, JPG, GIF, BMP, TIFF)
Raw Protocols:
- ESC/POS (receipt printers)
- ZPL (Zebra label printers)
- EPL (Eltron label printers)
PrintBridge consists of two components:
- Built with Tauri (Rust + WebView)
- Runs in system tray, minimal resource usage (~30MB)
- Handles downloads, caching, print queue
- Interfaces with OS print spooler
- Lightweight (~8KB gzipped)
- TypeScript with full type definitions
- Promise-based API with event emitters
- Works in all modern browsers
| Feature | PrintBridge | JSPM | QZ Tray |
|---|---|---|---|
| Setup complexity | Install & go | NPM + config | Certificates + ports |
| Memory efficiency | URL passthrough | Base64 bloat | File-based |
| Batch printing | Native | Manual loop | Supported |
| Raw printing | ESC/POS, ZPL, EPL | Limited | Full |
| Open source | MIT | Proprietary | Partial |
| External ports | No | Yes | Yes |
| Certificate management | No | No | Required |
- Rust 1.70+
- Node.js 18+
- Windows 10/11 with Visual Studio Build Tools
# Clone repository
git clone https://github.com/mattpilott/PrintBridge.git
cd PrintBridge
# Build agent
cd agent
cargo build --release
# Build SDK
cd ../sdk
npm install
npm run build# Agent tests
cd agent && cargo test
# SDK tests
cd sdk && npm test- Core agent with WebSocket server
- JavaScript SDK
- PDF and image printing
- Raw printing (ESC/POS, ZPL, EPL)
- Batch printing with error handling
- Windows support
- macOS support
- Print spooler status monitoring
- React hooks package
- Linux support
- Plugin system
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
- Bug reports: Open an issue with reproduction steps
- Feature requests: Describe the use case
- Code: Fork, branch, PR
MIT License - see LICENSE for details.
- GitHub Issues - Bug reports and feature requests
- Discussions - Questions and community chat