ZPL (Zebra Programming Language) is the text-based command language that Zebra thermal printers read to lay out and print a label. Instead of sending a picture, you send a short script of commands — where to put text, how to draw a barcode, what data to encode — and the printer rasterises it. Once you can read a few commands, ZPL stops looking cryptic.
Anatomy of a ZPL label
Every label is wrapped between two commands and made of “field” blocks:
^XA
^FO50,50^A0N,40,40^FDHello world^FS
^FO50,110^BCN,80,Y,N,N^FD12345678^FS
^XZ
^XA— start of the label format.^FO50,50— Field Origin: x=50, y=50 dots from the top-left.^A0N,40,40— scalable font 0, Normal orientation, 40×40 dots.^FD...^FS— Field Data (the content) then Field Separator (end of the field).^BCN,80,Y,N,N— a Code 128 barcode, Normal orientation, 80 dots tall, print the human-readable line.^XZ— end of the format; print it.
That’s the whole mental model: ^XA … a series of ^FO (position) + a field type (^A0 text, ^BC barcode, ^GB box, ^GF graphic) + ^FD data ^FS … ^XZ.
Dots, DPI and why size “changes”
ZPL measures everything in dots, and a dot’s physical size depends on the printer’s resolution:
| Resolution | Dots per mm | 1 mm = |
|---|---|---|
| 203 dpi | 8 | 8 dots |
| 300 dpi | ~12 | 12 dots |
| 600 dpi | ~24 | 24 dots |
So ^FO400,0 is 50 mm from the left on a 203 dpi printer, but ~33 mm on a 300 dpi one. If you design in millimetres and convert to dots using the target DPI, the same label prints at the correct physical size everywhere.
Common commands you’ll actually use
^A0N,h,w— scalable font (height, width in dots).^FB— field block for word-wrapped, multi-line text.^BY— barcode defaults (module width, ratio).^BC/^BE/^B3— Code 128 / EAN-13 / Code 39.^BQ— QR code.^GB— graphic box (borders, lines, filled blocks).^PW/^LL— print width / label length.~SD— darkness;^PR— print speed.
A worked example: a small product label
^XA
^PW400
^LL240
^FO20,20^A0N,30,30^FDAcme Coffee 250g^FS
^FO20,70^A0N,50,50^FD$12.90^FS
^FO20,140^BY2^BCN,70,Y,N,N^FD7891234567895^FS
^XZ
This prints a 50 × 30 mm label (at 203 dpi) with a product name, a price, and an EAN/Code 128 barcode with its human-readable digits.
How to preview ZPL without wasting labels
You don’t need to burn paper to check a layout. Labelary renders ZPL to an image via a web viewer and a REST API — paste your ZPL, pick the DPI and label size, and see exactly what will print. (ThermalDraw uses Labelary under the hood so its on-screen preview matches the printed result.)
Getting ZPL to the printer
- USB / serial: a driver or a local agent (QZ Tray, Zebra Browser Print) streams the raw ZPL.
- Network (TCP 9100): send the ZPL straight to the printer’s IP on port 9100.
- Cloud: Zebra’s Link-OS
SendFileToPrinter/ SendQuick APIs, or a print agent like PrintNode.
ZPL vs the other label languages
- ZPL — Zebra, the de-facto standard for barcode/product/shipping labels.
- EPL — older, simpler Zebra language; still around on legacy units.
- DPL — Datamax-O’Neil printers’ equivalent of ZPL.
- ESC/POS — receipt printers (thermal receipts/coupons), not die-cut labels.
Do you even need to write ZPL?
For one-off tweaks, hand-writing ZPL is fine. For real work — dynamic data, many SKUs, multiple printers — design the label visually and let a tool emit the ZPL. That’s exactly what ThermalDraw does: drag elements onto a to-scale canvas, bind {{variables}}, and export ZPL (or DPL, or ESC/POS) that’s byte-for-byte what the printer needs.
Frequently asked questions
What does ZPL stand for?
ZPL stands for Zebra Programming Language — the command language Zebra thermal printers use to describe and print labels.
Is ZPL the same as EPL?
No. EPL (Eltron Programming Language) is an older, simpler Zebra language. ZPL (specifically ZPL II) is the modern standard with more features. Most current Zebra printers default to ZPL.
How do I preview ZPL without a printer?
Use a ZPL renderer such as the Labelary online viewer or API, which turns ZPL into a PNG/PDF image of the label so you can check the layout before printing.
What units does ZPL use?
ZPL positions everything in dots, not millimetres. The dot size depends on the printer's resolution (203 dpi ≈ 8 dots/mm, 300 dpi ≈ 12 dots/mm), so the same ZPL prints at different physical sizes on different printers unless you account for DPI.
Design your label — free
Drag-and-drop in the browser, preview it, export ZPL / DPL / ESC/POS. Pay only to print at scale.
Open the editor →