python-escpos: a Python library for ESC/POS receipt printers
Python library to manipulate ESC/POS printers. python-escpos - Python library to manipulate ESC/POS Printers Description =========== ..
At a glance
- What is it?
- python-escpos wraps the ESC/POS command set in Python classes for USB, network and serial receipt printers, using escpos-printer-db profiles to pick the right commands per model. The last push was on 2023-12-17, so treat it as stable rather than moving.
- Who is it for?
- Adopt python-escpos when you already have a receipt printer and want to drive it from Python instead of a vendor SDK, and when you can name the model so you can pass a matching profile. Do not adopt it for label printers or anything that does not speak ESC/POS, and do not expect a fast-moving project: the last push was on 2023-12-17 and v3.1 is the newest release.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 11 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What python-escpos solves for receipt-printing Python code
ESC/POS is Epson's command set for receipt printers, and it is implemented loosely by many manufacturers. Sending a receipt means emitting byte sequences: control characters for bold, alignment, code pages, cut commands, plus encoded image and barcode data. Writing that by hand is tedious and model-dependent, because supported commands differ from printer to printer.
python-escpos is the Python layer over that. The README describes it as a library that gives a Python application access to printers handled by ESC/POS commands, and the feature list is concrete: text with alignment and font changes by size, type and weight; images; barcodes; QR codes; plus hardware functions such as cutting paper, control characters and printer reset.
The audience is narrow and identifiable. You are writing Python, you have a physical receipt printer, and you want to print from an application rather than from a vendor's Windows driver. That covers point-of-sale backends, kitchen ticket printers, kiosk software and small self-hosted services. If you never touch a printer, nothing here applies to you.
How the printer classes and escpos-printer-db profiles fit together
The library splits transport from command generation. Transport classes live in escpos.printer: Usb, Network and Serial are the ones the README demonstrates. Each opens a channel to the device and hands bytes to the printer.
Command generation is where the profiles come in. The README states that since supported commands differ from printer to printer, the software tries to automatically apply the right settings for the printer you set, and that these settings are handled by escpos-printer-db, the same database used by escpos-php. The README also carries a note recommending that you include a matching profile so the library knows the printer's capabilities.
That is the whole architecture in practice: you construct a transport with connection details plus a profile name, then call methods such as text, image, barcode, qr and cut on it. The profile decides which underlying command bytes a call maps to. Skip the profile and the library still works, but the README's note is a warning that capability detection is weaker. The repository ships capabilities-data as a submodule and packages a capabilities.json file with the escpos package, which is how the profile data reaches your installation.
Installing python-escpos and printing a first receipt
The project publishes to PyPI and the repository's requirements.txt is just an editable install of the package itself, so the normal route is pip. The setup.py declares a console entry point named python-escpos, which means the install also gives you a command-line tool.
pip install python-escposAfter that, the README's basic example constructs a USB printer by vendor and product ID and passes a profile. Note the comment in the README identifying the device as a Seiko Epson Corp. receipt printer, model EPSON TM-T88III, and the profile string matching that model.
from escpos.printer import Usb
p = Usb(0x04b8, 0x0202, 0, profile="TM-T88III")
p.text("Hello World\n")
p.image("logo.gif")
p.barcode('4006381333931', 'EAN13', 64, 2, '', '')
p.cut()The two hex values are the USB vendor and product IDs, so you must substitute the IDs your own printer reports. The README's network example is the same shape with an IP address instead, and the serial example passes devfile, baudrate, bytesize, parity, stopbits, timeout and dsrdtr before the profile.
from escpos.printer import Network
kitchen = Network("192.168.1.100", profile="TM-T88III")
kitchen.text("Hello World\n")
kitchen.barcode('4006381333931', 'EAN13', 64, 2, '', '')
kitchen.cut()What you should see is the text, then the image, then the barcode, then a paper cut. The repository's examples directory goes further than the README: receipt.py, barcodes.py, qr_code.py, font_variations.py, block_text.py and software_columns.py each target one feature, and several have a paired result image such as receipt_results.jpg and font_variations_result.jpg. There is also examples/docker-flask/ if you want to see the library behind an HTTP endpoint. Read those before designing your own layout.
Where python-escpos breaks down
The profile system is the main soft spot, and it is structural rather than a bug. The README says the library tries to automatically apply the right settings, and then immediately recommends passing a matching profile. That is an admission that the automatic path is not something to rely on. If your printer is not in escpos-printer-db, you are choosing between an approximate profile and no profile, and the failure mode is quiet: a font command that does nothing, a cut that does not fire, a code page that garbles accented characters. Nothing raises an exception when a printer silently ignores a command it does not implement.
Transport is the second constraint. USB access goes through pyusb, which on Windows generally means a libusb-style driver bound to the device, so the printer may stop being usable through its normal driver. The README does not document that trade-off, and the related search phrase about "no backend available" points at exactly this class of setup problem. If your environment cannot give Python raw access to the USB device, the Network or Serial classes are the way around it.
Finally, this is a library for ESC/POS. Label printers, laser printers, PDF generation and anything driven by a full page-description language are outside its scope. Using it as a general printing abstraction will not work.
python-escpos compared with escpos-php and vendor SDKs
The closest sibling is escpos-php, and the projects are related rather than merely similar: the README states that escpos-printer-db is used by both python-escpos and escpos-php. The difference is the host language and the integration surface. If your application is PHP, escpos-php fits without a second runtime; if it is Python, python-escpos does. Because they share the profile database, the printer coverage is largely the same, so the choice is about your stack, not about which printers work.
The other alternative is the vendor SDK or driver. Those are tied to one manufacturer and one operating system, and they usually expose a document model rather than raw ESC/POS. The trade-off is real in both directions: a vendor driver handles device quirks and firmware differences you would otherwise discover yourself, but it locks your code to that vendor and often to Windows. python-escpos gives you one Python API across USB, network and serial and across manufacturers, at the cost of doing your own profile selection and accepting that unsupported commands fail silently.
A third option, worth naming because it is not a library at all, is CUPS with a generic ESC/POS queue. That moves printing out of your application and into the operating system, which is convenient until you need precise control over cut timing, cash drawer pulses or barcode encoding. At that point you are back to emitting bytes, and python-escpos is the Python way to do it.
Maintenance, licensing and the cost of upgrading
The repository is not archived, but the last push was on 2023-12-17, and v3.1 carries that same date. v3.0 came on 2023-11-16 and v3.0a9 on 2023-05-11. There is no release after v3.1, so plan on a library that is stable rather than one receiving regular changes. For a protocol wrapper that is not automatically bad: ESC/POS itself is not moving quickly. It does mean that a printer released after the profile database was last updated may need manual handling.
The licence is MIT. That is permissive: you can use the library in closed-source and commercial applications, and you can modify it. Two practical notes rather than legal advice. First, the README carries a disclaimer that none of the vendors cited agree with or endorse the patterns or implementations, so do not read vendor model names in the profile data as any kind of certification. Second, the project bundles capabilities data from escpos-printer-db and ships a capabilities.json inside the escpos package, so if you vendor or redistribute the library, that data travels with it and has its own provenance.
Upgrade cost is dominated by the v3 line. Version 3.0 was a major release, and the pyproject.toml shows the test matrix covering Python 3.10 through 3.14 with tox. If you are on an older 2.x codebase, expect API changes around printer construction and profile handling; the CHANGELOG.rst in the repository root is the file to read before upgrading. The library uses setuptools_scm, so versions are derived from git tags rather than hand-edited.
Editorial conclusion
Adopt python-escpos when you already have a receipt printer and want to drive it from Python instead of a vendor SDK, and when you can name the model so you can pass a matching profile. Do not adopt it for label printers or anything that does not speak ESC/POS, and do not expect a fast-moving project: the last push was on 2023-12-17 and v3.1 is the newest release. Before writing production code, verify three things on your own hardware: that the connection class you picked (Usb, Network or Serial) actually reaches the device, that the profile you pass matches the model, and that cut and image output land where you expect. Start with the python-escpos CLI against one printer before building the receipt layout.
Frequently asked questions
How do I install python-escpos?
Install it from PyPI with pip install python-escpos. The setup.py declares a console entry point named python-escpos, so the install also provides a command-line tool alongside the escpos package.
Does python-escpos work on Windows?
The library itself is pure Python and the README shows no OS restriction, but USB printers go through pyusb, and the README does not document the driver situation on Windows. The Network and Serial classes avoid USB entirely, which is the usual workaround when USB access is unavailable.
Why does python-escpos need a printer profile?
The README states that supported commands differ from printer to printer and that the library tries to automatically apply the right settings for the printer you set, using escpos-printer-db. It then recommends including a matching profile so the library knows your printer's capabilities.
Can python-escpos print images and barcodes?
Yes. The README lists text, images, barcodes and QR codes as supported, and the basic example calls p.image, p.barcode and p.cut in sequence. Image support depends on Pillow and barcode generation on python-barcode and qrcode.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/python-escpos-python-escpos)