ESC/POS receipt printers
ESC/POS is the printing protocol every thermal receipt printer worth its salt understands. Fexl Lite’s desktop app (Tauri) prints receipts through ESC/POS over USB or network, falling back to the OS default printer when no ESC/POS path is configured. This page walks through the setup, the printer-discovery flow, and the troubleshooting steps when your receipt comes out blank, sideways, or in the wrong language.
How Fexl Lite picks a printer
The desktop app maintains one printer path per device, configured in Settings → Printer. When you press Print Receipt anywhere in the app, the receipt data flows from React → Tauri command → Rust receipt module, which inspects the path and picks one of four backends:
| Path pattern | Backend | When you’d use it |
|---|---|---|
usb:VENDOR:PRODUCT (e.g. usb:04b8:0e15) | USB driver | Direct USB cable to a thermal printer. Best path. |
IP:PORT (e.g. 192.168.1.50:9100) | Network driver | Network thermal printer on the same LAN. |
/dev/usb/lp0, COM3, or any existing file path | File / COM port driver | Linux/macOS USB device files; Windows COM ports. |
| (empty / unset) | OS default printer | Falls through to CUPS on macOS/Linux or the Windows default printer. Plain text only — no ESC/POS formatting. |
The first three are the ESC/POS path: bold text, monospace alignment, the cut command at the end. The OS default fallback is for “I just want a receipt to print somehow” — it lays out the same content as plain text and runs through whatever default printer your OS knows about.
Setting up a USB printer
The most reliable path. Plug in, configure, print.
Plug the printer in
USB cable directly into the desktop. Power on. The OS may briefly show a “new device” notification — that’s fine; you don’t need to install vendor drivers for ESC/POS.
Open Settings → Printer
The page lists every printer the app discovered, in three buckets:
- USB Printers — auto-detected via the
usbfeature. Each entry shows the vendor:product ID and the manufacturer/product name reported by the device. - Network Printer (Configure IP:PORT) — placeholder entry for a network printer you’ll configure manually.
- Windows Default Printer (Windows only) — fallback to whatever Windows prints to by default. Plain text, not ESC/POS.
Pick your USB printer
Tap the row. The path field updates to usb:VENDOR:PRODUCT. Save.
Print a test receipt
Open Settings → Printer → Test Print. A short test receipt prints with the store name, a few placeholder lines, and a barcode. If the cut line fires at the bottom, you’re done.
Setting up a network printer
For shared printers in a back-office or warehouse setup.
Find the printer's IP
Most thermal printers print a self-test page on power-up that includes the assigned IP. If it’s DHCP, pin it to a static address in your router so the path doesn’t drift.
Pick the network printer entry in Settings → Printer
An IP:PORT input field appears. Type 192.168.1.50:9100 (port 9100 is the de-facto standard for ESC/POS over network). Save.
Test print
Same as USB. If the receipt comes out, you’re done. If not, check the troubleshooting section below — most network issues are firewall or wrong-port.
What’s on a receipt
The Rust receipt builder writes a fixed structure:
- Header — store name (centered, bold), tagline if set, store address and phone.
- Invoice metadata — invoice number, date, cashier, customer name (if attached), payment type.
- Optional title — the user-supplied title from manual invoices (“PHONE REPAIR”, centered, bold). Only present on manual / titled invoices.
- Line items — name, quantity, unit price, line total. Wraps long names across two lines using the
RECEIPT_WIDTHconstant (48 characters for ESC/POS). - Totals — subtotal, VAT, discount, shipping, TOTAL (bold).
- Payment breakdown — the methods used and amounts, with a Cash Tendered / Change Due block when applicable.
- Optional barcode or QR — the invoice number rendered as either a Code 128 barcode or a QR code, configurable per template.
- Footer — thank-you line, optional return policy, optional WhatsApp / Telegram links.
- Cut command — the printer cuts the paper.
For card-only payments, the Change Due line is suppressed (you can’t give cash change on a card payment, so showing zero is just noise). For split payments, the per-method rows show the net amount each method paid — they sum to the invoice total. #59 v1.6.100 made this correct on the customer-print path too; previously the change-due line could leak through.
Re-printing a receipt
Two paths in:
- Invoice detail page → Print Receipt — re-prints the receipt for any past invoice, using the device’s current printer path. Useful for replacement receipts or proof-of-sale.
- POS → Last Sale → Print — re-prints the most recent invoice without leaving the till.
The receipt always reflects the current state of the invoice — if it’s been refunded or cancelled since the original print, the re-print shows that. For serialised items, the receipt re-fetches by ID before printing so the real serial number renders, not a stale or stringified value. #62 v1.6.100
Troubleshooting
For symptom-to-fix walkthroughs, see Printing issues. Quick reference:
Receipt prints blank, with garbled characters, or as the wrong language
Most likely the printer is in CP437 (American) code page mode and the app is sending UTF-8. Switch the printer’s code page in its self-test menu — most thermal printers have a switch or web admin for this. For Arabic stores, set the printer to CP864 or Windows-1256 depending on the model; Fexl Lite emits Arabic glyphs as bytes the printer’s code page must match.
Cut command doesn’t fire
The printer’s cut blade is disabled in firmware, or the model doesn’t support cutting (cheaper models). Set Auto-cut off in Settings → Printer if you’d rather tear by hand than wait for the timeout.
”USB printer not found” after a reboot
The vendor:product pair changed. Re-pick the printer from Settings → Printer; the path stamp updates.
Network printer hangs, then errors
Port is wrong (try 9100, 515, or check the printer’s web admin), or the printer’s IP changed (DHCP — pin it static), or the firewall blocks port 9100 outbound on your network.
Default-printer fallback prints garbage
The OS default fallback writes plain text — it doesn’t speak ESC/POS. If your receipt shows a wall of ^[!@^[!a^[!E1 escape sequences, the desktop is using the OS-default backend with an ESC/POS-only printer driver. Fix the path: either switch the printer driver to a “generic text” driver in OS settings, or configure the ESC/POS path properly in Settings → Printer.
Related
- Settings → Printer — the in-app configuration page
- Print A4 / Thermal — choosing between A4 PDFs and thermal receipts
- Printing issues — full symptom-to-fix table
- Install on Windows / macOS — the desktop app is a precondition
- Settings → Invoice templates — what’s on the receipt and how to customise it