Skip to main content

Thermal Printing Router

·333 words·2 mins
Hakan Ates
Author
Hakan Ates
I build full-stack applications and LLM-powered tools.
A local Electron bridge that lets Dishup’s cloud POS print fiscal receipts on the restaurant’s LAN thermal printers, which a browser cannot reach on its own.
Electron manager UI showing the local service on port 9080 and per-printer config for a registered EPSON TM-M30II
Electron manager UI showing the local service on port 9080 and per-printer config for a registered EPSON TM-M30II

Highlights
#

  • Built a cross-platform Electron bridge (Node.js, TypeScript) letting Dishup’s browser POS print fiscal receipts on LAN printers the browser can’t reach.
  • Unified three fiscal printer vendors (AXON, CUSTOM, EPSON via ESC/POS) behind a single local HTTP/S API, independent of the installed hardware.
  • Shipped a management UI with per-printer configuration, test prints, per-printer status tracking that surfaces failures, and an EN/IT language toggle.

How it works
#

flowchart LR
    POS[Cloud POS in browser] -->|HTTPS :9080| SVC[Local print service]
    SVC --> RT{Vendor routing}
    RT --> AX[AXON adapter]
    RT --> CU[CUSTOM adapter]
    RT --> EP[EPSON adapter, ESC/POS]
    EP --> PR[TM-M30II at 192.168.1.24:9100]
    SVC --> UI[Manager UI: status, add/test/delete]

Case Study
#

Problem. In Italy, receipts must be issued through certified fiscal printers. Dishup’s POS runs as a web app in an HTTPS secure context, and a browser cannot open raw connections to printers sitting on the restaurant’s local network. On top of that, each printer vendor speaks its own protocol.

Approach. I built an Electron app that runs on the restaurant’s machine and acts as the trusted local bridge: it exposes an HTTP/S service on port 9080 that the cloud POS calls to print. The bridge was the forcing reason for the app to exist at all, and once it was there it became the natural place to hide vendor differences, so I put AXON, CUSTOM, and EPSON behind one printing API. Printer failures are tracked per device and surfaced in the manager UI rather than dropped silently.

Outcome. Shipped as part of Dishup’s POS during my internship (May to Nov 2024). Restaurant staff manage printers through the built-in UI, available in English and Italian.

Stack
#

Electron, Node.js, TypeScript, local HTTP/S service, ESC/POS and vendor-specific protocols (AXON, CUSTOM, EPSON).