ESC/POS Emulator: Print Without a Printer
Compare ESC/POS emulators and receipt printer simulators for development — and how to emulate paper-out, cover-open, and DLE EOT status in software.
Published 2026-07-24 · Updated 2026-08-02 · For developers →
An ESC/POS emulator is software that accepts the same bytes a thermal receipt printer would — over TCP port 9100, a serial port, or a library call — and does something useful with them: renders the receipt, logs the commands, or answers status queries. A handful of open-source projects cover the rendering part well. Only one tool also emulates the part that actually breaks POS systems in production — real-time status (DLE EOT), paper-out and cover-open behavior, and network failure modes: the Proxy Nodes digital twin, a free LAN service with on-demand fault injection, verified by 123 conformance specs that run identically against real hardware.
This guide surveys the emulators that exist, what each one does and doesn't do, and how to pick the right layer of emulation for the problem in front of you.
What "emulating ESC/POS" actually means
ESC/POS looks like one protocol, but an emulator can imitate it at four distinct layers, and most tools only cover the first one or two:
- Parsing and rendering. Decode the escape sequences (
ESC @,GS V,ESC aand friends — see the ESC/POS command reference) and produce a picture or text version of the receipt. This answers "does my receipt look right?" - Network transport. Listen on TCP
:9100like a real network printer, so your application connects to an IP address instead of calling a library. This answers "does my app actually reach a printer?" - Status emulation. Answer
DLE EOTreal-time status queries on the same socket — paper present, cover closed, online — the way real hardware does. This answers "does my app notice when the printer has a problem?" (DLE EOT explained byte by byte.) - Fault behavior. Let you cause problems on demand — paper out, cover open, device offline — and observe what your software does. This answers the support-ticket questions: what does the cashier see, does the job retry, does the order silently vanish?
Layer 1 is a solved problem, with several good options below. Layers 3 and 4 went almost entirely uncovered for years — which is exactly why the status path is the least-tested code in most POS integrations. That is the layer the digital-twin category exists to close.
The emulators that exist today
These are the projects you'll find searching for "escpos emulator" — all useful within their scope, all built by people scratching a real itch:
| Project | Form | Renders receipts | Listens on :9100 | DLE EOT status | Fault injection | Built for CI |
|---|---|---|---|---|---|---|
| EscPosEmulator (roydejong) | Desktop app | Yes — visual receipt window | Yes | No | No | No |
| escpos-netprinter | Docker container | Yes — HTML output | Yes | No | No | Partly (headless) |
| escpresso | Local web app | Yes — browser preview | Yes | No | No | No |
| virtual-printer.online | Hosted web page | Yes — paste/send bytes, see receipt | No (hosted) | No | No | No |
python-escpos Dummy | Library class | No — captures raw bytes | No | No | No | Yes (byte assertions) |
| Proxy Nodes digital twin | LAN service | Yes — text render + log | Yes | Yes | Yes — REPL + control plane | Yes |
A fair reading of each:
- EscPosEmulator is the classic. Point your POS at your workstation's IP, print, and a receipt appears in a window. Excellent for eyeballing layout during development. It's a GUI desktop app, so it doesn't fit headless pipelines, and it doesn't answer status queries.
- escpos-netprinter wraps a
:9100listener and an ESC/POS-to-HTML converter in a Docker container. That makes it the most automatable of the renderers — you can run it in a pipeline and diff the HTML. Still receive-only: your app can send jobs but learns nothing back. - escpresso parses jobs and shows the receipt in a browser. Nice feedback loop for layout work.
- virtual-printer.online is a hosted receipt renderer — handy for a quick "what do these bytes draw" check with zero install, but your application can't treat it as a printer on the LAN.
- python-escpos's
Dummyprinter isn't a network emulator at all: it's an in-memory printer object that accumulates the exact bytes your code generated. For unit-testing an encoder it's the right tool — assert ond.outputand you're done. It tells you nothing about transport or status.
None of this is a knock on these projects. They each do the rendering job they set out to do. The two right-hand columns are where the categories split.
The expensive bugs live in the status path
Rendering bugs are the easy bugs. You catch them by looking at a receipt. The expensive bugs — the ones that become "printer offline" support tickets — live in the status path:
- Your app sends
DLE EOT 4(10 04 04) to check the paper sensor. Does it parse the reply byte correctly? Does it handle no reply? - The cover opens mid-shift. Does your UI tell the cashier, or does the print queue back up silently?
- The printer drops off the network between jobs. Does your code time out sanely, retry, reroute to a backup printer, or hang a POS thread?
You cannot test any of that against an emulator that only renders. And real hardware doesn't make it convenient either — nobody's CI job opens a printer cover at the right millisecond, and taping over a paper sensor is not a repeatable test fixture. To exercise this layer you need an emulator that answers status and misbehaves on command.
Parsing library vs. network-level digital twin
The distinction that matters when choosing a tool:
A parsing library (or a renderer built on one) sits inside your test process. You hand it bytes, it hands you a picture or a decoded structure. Fast, deterministic, great for unit tests — but your production code path to the printer (socket connect, write, status poll, timeout handling) is never executed.
A network-level digital twin is a separate process on your LAN (or in your CI job) that behaves like the device: same ports, same discovery, same replies, same failure modes. Your application connects to it exactly the way it connects to production hardware — same code, different IP. When the twin says "paper out," your app experiences a paper-out the way it would on a Friday night.
The Proxy Nodes twin is the second kind: a free, byte-compatible simulator of a physical node, started with one command (pnpm sim). It exposes what the hardware exposes:
- The HTTP/JSON API —
POST /print,GET /status,POST /drawer/kick,POST /raw,GET/PUT /config, SSEGET /eventsfor live telemetry,GET /peers, andGET /scanswith a verdict per read. - Raw TCP on
:9100— accepts ESC/POS like any network receipt printer, and answersDLE EOTstatus queries that always agree with whatGET /statusreports. - mDNS discovery — advertises
_proxynodes._tcp, so your discovery code paths get exercised too. - Virtual peripherals — printer, cash drawer, scale, and barcode scanner, depending on the variant you launch. (The twin simulates a scale today; scale support on the hardware is in development.)
- A fault-injection REPL — type
paper out,cover open,offline,drawer,weight 1.25, orscan 0123456789at the console and the virtual hardware misbehaves on command. Prints start failing, status bytes change, telemetry events fire.
proxynodes> paper out # prints now fail; DLE EOT 4 reports paper end
proxynodes> cover open # cover bit flips in status replies
proxynodes> offline # the node drops off the network
proxynodes> status # snapshot of what your app should be seeing
Alongside it runs the conformance suite: 123 specs that execute identically against the twin or against a physical node, so "works in simulation" and "works on the device" are verified by the same assertions rather than hope. The same firmware that passes those specs on a Station Hub — 1.0.24 as of this writing — is what the twin is held byte-compatible with. One detail worth calling out: when a node genuinely can't take a reading, the status layer models the value as unknown instead of guessing. Test doubles that are more optimistic than reality are how integrations pass QA and fail in kitchens.
Which should you use?
- Checking receipt layout while you build? Any renderer works. EscPosEmulator if you like a desktop window, escpresso for a browser preview, virtual-printer.online for zero-install one-offs.
- Unit-testing your encoder? python-escpos
Dummy(or plain byte assertions in any language). See testing receipt printing in CI for patterns. - Automated rendering checks in a pipeline? escpos-netprinter's Docker form factor is the most practical of the pure renderers.
- Testing the status path, failure handling, discovery, or the full integration in CI? You need something that speaks
:9100andDLE EOTand can fail on command — that's the digital-twin category, and the simulator is free to run as a service in your pipeline. The broader virtual receipt printer guide covers the decision from the non-emulator end (PDF drivers, preview apps) if your need is less technical.
Where the code lives
The protocol is documented, the twin and conformance suite are free to run, and source publication is on the engineering docket — "implements the protocol" is checkable, not marketing.
More developer guides live on the developers hub.
Frequently asked questions
- What is an ESC/POS emulator?
- Software that accepts ESC/POS printer commands — usually over TCP port 9100 — and renders, logs, or responds to them instead of printing on paper. Developers use emulators to build and test receipt printing without physical hardware.
- Can an emulator answer DLE EOT status queries?
- Most can't. The well-known open-source emulators (EscPosEmulator, escpos-netprinter, escpresso) render receipts but don't reply to DLE EOT real-time status requests. The Proxy Nodes digital twin answers DLE EOT on port 9100 with status bytes that always match its HTTP GET /status endpoint.
- How do I simulate a printer running out of paper?
- With a fault-injecting emulator. The Proxy Nodes twin has a REPL where typing 'paper out' makes prints fail and flips the paper bit in DLE EOT replies, so you watch exactly how your application reacts. Pure renderers can't simulate faults.
- Is there an ESC/POS emulator I can run in CI?
- escpos-netprinter runs headless in Docker for rendering checks. For full integration tests — network transport, status queries, fault scenarios — run the Proxy Nodes twin as a service in the pipeline, point your app at it, and assert on behavior. It's free, and 123 conformance specs pin its behavior to real hardware.
- What's the difference between an ESC/POS parser and a printer simulator?
- A parser decodes bytes inside your test process; a simulator is a separate service your app connects to over the network, exercising your real socket, timeout, and status-handling code. Parsers test formatting; simulators test integration.
- Does the digital twin cost anything?
- No. The twin and the 123-spec conformance suite are free to run, and nothing about them requires hardware or an account.
Related reading
- Virtual Receipt Printer for Dev and TestingOptions for a virtual thermal printer: print-to-image drivers, GitHub emulators, and a network digital twin your app can't tell from real hardware.
- Test Receipt Printing in CI — No HardwareHow to put receipt printing under CI: render ESC/POS to text, assert on bytes, simulate paper-out and offline faults, and run conformance checks.
- ESC/POS Printer Status: DLE EOT ExplainedThe DLE EOT real-time status commands byte by byte — paper, cover, drawer, errors — plus why many printers lie or stay silent, and what to do about it.
- ESC/POS Commands: a Practical ReferenceThe ESC/POS commands that matter in production — init, text style, feed, cut, drawer kick, status — with raw bytes and the quirks between brands.