ESC/POS Rust implementation
This crate implements a subset of Epson's ESC/POS protocol for thermal receipt printers. It allows you to generate and print documents with basic text formatting, cutting, barcodes, QR codes and raster images on a compatible printer. It also provides a way to check the printer status.

Printed on Aures ODP 333
This project is strongly inspired by recibo (Rust), escposify (Rust) and escpos (Go).
Installation
For standard functionalities (e.g., printing text), no additional dependencies are required:
[]
= "0.19.0"
If you need all features, you can use the full feature:
[]
= { = "0.19.0", = ["full"] }
Or you can use cargo add command:
Code coverage
Tool used: tarpaulin
cargo install cargo-tarpaulin
cargo tarpaulin --all-features --tests
Results:
- [2025-09-15]
57.62% coverage, 1172/2034 lines covered
MSRV
Tool used: cargo-msrv
cargo install cargo-msrv
cargo msrv find
cargo msrv verify
Features list
| Name | Description | Default |
|---|---|---|
std |
Enable std support (disable for no_std + alloc environments) |
✅ |
barcodes |
Print barcodes (UPC-A, UPC-E, EAN8, EAN13, CODE39, ITF or CODABAR) | ✅ |
codes_2d |
Print 2D codes (QR Code, PDF417, GS1 DataBar, DataMatrix, Aztec, etc.) | ✅ |
graphics |
Print raster images (requires std) |
❌ |
usb |
Enable USB feature (requires std) |
❌ |
native_usb |
Enable native USB feature (requires std) |
❌ |
hidapi |
Enable HidApi feature (requires std) |
❌ |
serial_port |
Enable Serial port feature (requires std) |
❌ |
usbprint |
Enable Windows USB print driver (usbprint.sys via Win32 API) |
❌ |
ui |
Enable ui feature (UI components) | ❌ |
full |
Enable all features | ❌ |
no_std support
The crate can be used on bare-metal targets (microcontrollers, kernels…) by disabling default features. Only alloc is
required:
[]
= { = "0.18", = false, = ["barcodes", "codes_2d"] }
The built-in Console, Network and File drivers as well as the graphics feature require
std. In no_std mode you implement the Driver trait for your peripheral (UART, SPI, USB endpoint, …) and pass it to
Printer::new. The Printer::driver accessor lets you recover the driver from a Printer.
See examples/no_std_codes.rs for a minimal example with a custom in-memory driver and
barcodes / 2D codes — all the protocol-level APIs (barcodes, QR Code, PDF417, DataMatrix, Aztec, MaxiCode, page codes,
status…) work in no_std. The codes themselves are rendered by the printer's firmware: the crate only serializes the
ESC/POS commands, so the embedded-side cost is minimal.
Examples
The examples folder contains various examples of how to use escpos.
The docs also provide code snippets and examples.
To launch an example, use the following command:
RUST_LOG=debug cargo run --example full --features full
The list of all the examples can be found here.
Simple text formatting
use Printer;
use PrinterOptions;
use *;
use ;
EAN13
use Printer;
use *;
use ;
QR Code
use Printer;
use *;
use ;
Bit image (with graphics feature enabled)
use Printer;
use *;
use ;
Windows USB print driver (with usbprint feature enabled, Windows only)
Drives a POS printer through the standard Windows usbprint.sys kernel driver using the Win32 API (CreateFile /
ReadFile / WriteFile). No Zadig / WinUSB / libusb swap required — the device keeps working with the regular Windows
print spooler at the same time.
use Printer;
use *;
use ;
Check printer status
use Printer;
use *;
use ;
Commands list
| Status | Command | Description | Feature |
|---|---|---|---|
| ✅ | init() |
Initialize printer (ESC @) |
|
| ✅ | print() |
Print document | |
| ✅ | reset() |
Hardware reset (ESC ? LF 0) |
|
| ✅ | cut() |
Paper cut (GS V A 0) |
|
| ✅ | partial_cut() |
Partial paper cut (GS V A 1) |
|
| ✅ | print_cut() |
Print and paper cut | |
| ✅ | page_code() |
Select character code table (ESC t) |
|
| ✅ | character_set() |
Select an international character set (ESC R) |
|
| ✅ | bold() |
Text bold (ESC E) |
|
| ✅ | underline() |
Text underline (ESC -) |
|
| ✅ | double_strike() |
Text double strike (ESC G) |
|
| ✅ | font() |
Text font (ESC M) |
|
| ✅ | flip() |
Text flip (ESC V) |
|
| ✅ | justify() |
Text justify (ESC a) |
|
| ✅ | reverse() |
Text reverse color (GS B) |
|
| ✅ | size() |
Text size (GS !) |
|
| ✅ | reset_size() |
Reset text size (GS !) |
|
| ✅ | smoothing() |
Smoothing mode (GS b) |
|
| ✅ | feed() |
Line feed (ESC d) |
|
| ✅ | feeds() |
Multiple lines feed (ESC d) |
|
| ✅ | line_spacing() |
Line spacing (ESC 3) |
|
| ✅ | reset_line_spacing() |
Reset line spacing (ESC 2) |
|
| ✅ | upside_down() |
Upside-down mode (ESC {) |
|
| ✅ | cash_drawer() |
Generate pulse (ESC p) |
|
| ✅ | write() |
Write text | |
| ✅ | writeln() |
Write text and line feed | |
| ✅ | custom() |
Custom command | |
| ✅ | custom_with_page_code() |
Custom command with page code | |
| ✅ | motion_units() |
Set horizontal and vertical motion units (GS P) |
|
| ✅ | ean13() |
Print EAN13 with default option | barcode |
| ✅ | ean13_option() |
Print EAN13 with custom option | barcode |
| ✅ | ean8() |
Print EAN8 with default option | barcode |
| ✅ | ean8_option() |
Print EAN8 with custom option | barcode |
| ✅ | upca() |
Print UPC-A with default option | barcode |
| ✅ | upca_option() |
Print UPC-A with custom option | barcode |
| ✅ | upce() |
Print UPC-E with default option | barcode |
| ✅ | upce_option() |
Print UPC-E with custom option | barcode |
| ✅ | code39() |
Print CODE 39 with default option | barcode |
| ✅ | code39_option() |
Print CODE 39 with custom option | barcode |
| ✅ | codabar() |
Print CODABAR with default option | barcode |
| ✅ | codabar_option() |
Print CODABAR with custom option | barcode |
| ✅ | itf() |
Print ITF with default option | barcode |
| ✅ | itf_option() |
Print ITF with custom option | barcode |
| ✅ | qrcode() |
Print QR code with default option | codes_2d |
| ✅ | qrcode_option() |
Print QR code with custom option | codes_2d |
| ✅ | bit_image() |
Print raster bit image with default option | graphics |
| ✅ | bit_image_option() |
Print raster bit image with custom option | graphics |
| ✅ | bit_image_from_bytes() |
Print raster bit image from bytes with default option | graphics |
| ✅ | bit_image_from_bytes_option() |
Print raster bit image from bytes with custom option | graphics |
| ✅ | gs1_databar_2d |
Print 2D GS1 DataBar with default option | codes_2d |
| ✅ | gs1_databar_2d_option |
Print 2D GS1 DataBar with custom option | codes_2d |
| ✅ | pdf417 |
Print PDF417 with default option | codes_2d |
| ✅ | pdf417_option |
Print PDF417 with custom option | codes_2d |
| ✅ | maxi_code |
Print MaxiCode with default option | codes_2d |
| ✅ | maxi_code_option |
Print MaxiCode with custom option | codes_2d |
| ✅ | data_matrix |
Print DataMatrix with default option | codes_2d |
| ✅ | data_matrix_option |
Print DataMatrix with custom option | codes_2d |
| ✅ | aztec |
Print Aztec code with default option | codes_2d |
| ✅ | aztec_option |
Print Aztec code with custom option | codes_2d |
| 🚧 | graphic() |
Print raster graphic with default option | graphics |
| 🚧 | graphic_option() |
Print raster graphic with custom option | graphics |
| ✅ | draw_line() |
Print a line | ui |
- ✅ Done
- 🚧 In progress
- ❌ To do
Page codes list
| Code | Implemented? |
|---|---|
| PC437 | ✅ |
| Katakana | ✅ |
| PC850 | ✅ |
| PC860 | ✅ |
| PC863 | ✅ |
| PC865 | ✅ |
| Hiragana | ❌ |
| PC851 | ✅ |
| PC853 | ✅ |
| PC857 | ✅ |
| PC737 | ✅ |
| ISO8859_7 | ✅ |
| WPC1252 | ✅ |
| PC866 | ✅ |
| PC852 | ✅ |
| PC858 | ✅ |
| PC720 | ❌ |
| WPC775 | ✅ |
| PC855 | ✅ |
| PC861 | ✅ |
| PC862 | ✅ |
| PC864 | ❌ |
| PC869 | ✅ |
| ISO8859_2 | ✅ |
| ISO8859_15 | ✅ |
| PC1098 | ❌ |
| PC1118 | ✅ |
| PC1119 | ✅ |
| PC1125 | ✅ |
| WPC1250 | ✅ |
| WPC1251 | ✅ |
| WPC1253 | ✅ |
| WPC1254 | ✅ |
| WPC1255 | ❌ |
| WPC1256 | ❌ |
| WPC1257 | ✅ |
| WPC1258 | ❌ |
| KZ1048 | ✅ |