charlieuki/receiptprinter
A PHP library for printing receipts on thermal ESC/POS printers. It supports USB, network, Windows and Linux connections, with a simple API for formatting text, images, barcodes and QR codes. Easily integrated into Laravel or any PHP application.
Build vs. buy for receipt printing. This package answers a recurring "do we build an ESC/POS layer ourselves?" question. It bundles the plumbing that is tedious but not differentiating: printer discovery/connection (USB, network/socket, Windows shared, CUPS), text formatting and alignment, bolding, font sizing, QR codes, 1D/2D barcodes, paper cut, and — as of release 1.2.5a, but not yet verified — image/logo printing (printLogo()) and cash-drawer kick (openDrawer()). For a PM, the core formatting/connection layer is roughly 2–4 weeks of engineering you do not have to schedule — a direct input into roadmap capacity planning. The two new functions do not yet count toward that saving until they pass testing; budget ~0.5–1 day to validate each and a small fallback if either fails.
Feature feasibility for in-store and back-of-house workflows. It makes the following cheap to scope and prototype:
openDrawer(), but treat it as unproven until tested against your target drawer/printer combination. If it fails, this becomes a small in-house ESC/POS escape-sequence job, not a blocker.Architecture decision: server-side vs. client-side printing. Because this is a server-side PHP library, adopting it commits you to a model where the web server (or a local print agent) talks directly to printers on the LAN. That is a genuine architectural fork in the road: it favors fixed-installation venues with network printers and stable networks, and it is a poor fit for browser-only/PWA or mobile-first products. Treat this as an architecture decision record, not a library choice.
Hardware compatibility and procurement policy. The library's implicit supported set — ESC/POS-compatible thermal printers (Epson TM family, Star, generic 58mm/80mm units) — becomes your recommended-hardware list. That informs procurement standards, support runbooks, and what your ops team is allowed to buy. Note that printLogo() is brand-new and untested, and logo rendering is historically the most printer-model-sensitive feature (raster vs. column-mode, memory limits on 58mm units). Do not publish "we support logos" to ops until two representative models pass.
Vendor lock-in posture. It is a thin, framework-agnostic PHP wrapper rather than a cloud printing SaaS. Choosing it is a deliberate decision to keep receipt rendering in your own codebase and avoid per-printer subscription fees from vendors like Star CloudPRNT or Epson Server Direct Print — at the cost of owning printer fleet support.
Release-cadence signal (updated). The new tag 1.2.5a is an alpha whose own release notes say the added functions "still need testing." A single untested alpha after roughly three years of dormancy is not evidence of active maintenance; it is evidence that untested code landed on the default branch. Do not let it reset your dependency-governance risk rating, and do not auto-track this version.
What it does not decide for you. No Laravel service provider, config publishing, facades, or queue integration. If you want PrintReceipt::dispatch($order) on a queue with retries, you are writing that adapter yourself. Budget for it explicitly rather than assuming "Laravel package" means drop-in.
Adopt (or, more accurately, vendor in and pin) when:
printLogo()/openDrawer() — not pixel-perfect branded artwork.Look elsewhere when:
openDrawer() is fire-and-forget — it does not tell you whether the drawer actually opened.1.2.5a, an alpha shipped with unverified functionality. Before shipping this in a commercial product, get legal sign-off on the actual LICENSE file, and assume no upstream fixes: you are the maintainer now.Pin deliberately (new decision). 1.2.5a is opt-in, not a default upgrade. Options: (a) stay on the last stable release and implement logo/drawer yourself via raw ESC/POS bytes (low effort for the drawer, moderate for the logo), or (b) fork at 1.2.5a to get both functions, then harden them yourself. The a suffix means the author is not claiming stability; your fork should not either until it is covered by tests.
Practical evaluation gate (2–3 days of engineering, up from 1–2):
printLogo() with a real logo on both models — monochrome, size-correct, no garbled output, acceptable latency on 58mm.openDrawer() against your actual cash drawer via the target printer port, and confirm the drawer does not open spuriously on normal receipts.If any of those fail, the decision is made. Steps 4–5 are the ones most likely to fail, and both should be treated as "we may write this ourselves" rather than "this is done."
For executives — one paragraph: Receipt printing is a solved problem we should not spend engineering quarters on. This library is a small, free, open-source PHP component that already speaks the standard language of thermal receipt printers (ESC/POS) and works over network, USB, and shared-printer connections. Adopting it as an internal, pinned dependency lets us ship in-store receipts, kitchen tickets, and end-of-day reports weeks earlier and at effectively zero license cost, instead of building and maintaining a printer driver layer ourselves. The trade-off is that the project is not actively maintained and its license needs a one-time legal check — so we will fork it, own it, and pair it with a print-queue adapter that we control. A very recent alpha added logo printing and cash-drawer support, but the author flags them as untested; we will validate them before promising either to sales or ops. We recommend it for fixed-installation venues with standard thermal printers; we do not recommend it for browser-only or mobile-first checkouts.
For engineering — the honest summary: Framework-agnostic PHP, ESC/POS command builder with multiple connector classes (USB, network socket, Windows shared, CUPS). Gives us formatting, QR/barcode, cut, and — new in 1.2.5a — printLogo() and openDrawer(), both explicitly marked by the author as "still needs testing." No Laravel integration: no service provider, no config, no queue, no events, no retries, no logging. Previous tagged release 2021-11-20; the only release since is an alpha, zero dependents, license still flagged NOASSERTION. Plan to fork and vendor it, wrap it behind our own ReceiptPrinter interface so we can swap the transport later, add a queued job with retry/backoff and structured logging around it, and write transport-level tests against a fake socket. Additionally: write regression tests for printLogo() and openDrawer() and review the new code paths before relying on them — the drawer kick in particular is a one-line escape sequence we could reimplement trivially if the upstream version proves unreliable. Estimated integration effort: ~2–3 days for the adapter and tests, plus ~0.5–1 day to validate the two new functions, versus ~2–4 weeks to build equivalents from scratch.
For operations/support — what they must know: We will publish a short list of supported printer models. Printing is initiated by our server, so the printer must be reachable on the venue network or shared from the till PC's OS. There is no automatic retry or paper-out alert in v1 — staff will reprint from the order screen, and we will log every print attempt so support can diagnose failures without a site visit. Logo printing and cash-drawer opening are being validated now; do not include them in venue onboarding scripts or staff training until we confirm them on the standard hardware, and expect a possible short delay on drawer-kick rollout.
How can I help you explore Laravel packages today?