Published: · Updated:
ZPL and CPCL both come from Zebra, which makes people expect them to be dialects of one language. They are not. They were designed for different machines under different constraints, and almost every difference follows from that: ZPL for stationary printers with loaded media of known size, CPCL for battery-powered units printing receipts and labels on a belt.
| Concept | ZPL | CPCL |
|---|---|---|
| Job start | ^XA |
! 0 200 200 210 1 — a header carrying offset,
resolution, height and copies |
| Argument separator | Positional after the command prefix | Spaces (not commas) |
| Label height | ^LL |
In the ! header |
| Copies | ^PQ |
Last field of the ! header |
| Text | ^FO50,50^A0N,40,40^FDHello^FS |
TEXT 4 0 50 50 Hello |
| Rotated text | Orientation letter in ^A |
Separate commands: TEXT90, TEXT180,
TEXT270 |
| Job end | ^XZ | PRINT |
The header is the difference that trips people first. In ZPL the label
size and copy count are commands you can add anywhere in the format; in
CPCL they are fields of the opening line, so a job without a proper
! line is not a job with defaults — it is a job whose size
and quantity nobody stated.
A desk printer knows what media is loaded, is plugged into power, and prints the same label shape thousands of times. A mobile unit does not: the roll is narrow, the battery level changes how darkly it burns, and the operator is standing in a doorway. CPCL puts the whole job description in a compact header because a mobile job is often generated on the spot for one item, not merged from a template.
That also explains the practical advice you hear about each. On desk
printers, the recurring problems are template-level: coordinates, media
mismatch, resolution. On mobile printers they are physical: contrast,
battery, roll width — which is why CPCL exposes CONTRAST,
TONE and SPEED as first-class commands.
Short answer: ZPL, unless the printer is a mobile unit that only speaks CPCL. Zebra's own developer guidance says the same: ZPL is the language that keeps getting features, CPCL and the other legacy languages get bug fixes; ZPL has the broadest font and localisation support; and it runs on nearly every Zebra model, so a format moves between printers without a rewrite. CPCL wins only where it was designed to — receipt-style output from a belt printer (ZQ/QLn series) driven directly by an app, or an existing CPCL code base that is not worth migrating.
Before you send either, check what the printer is set to. A
Link-OS printer accepts an SGD query over any connection:
! U1 getvar "device.languages" — and
! U1 getvar "allcv" lists the values that model allows.
Switching is ! U1 setvar "device.languages" "zpl" followed by
a reset; on a mobile printer defaulted to line_print the ZPL
you send is silently ignored until you do. If the printer is driven through
a Windows driver, the driver's language must match too (Zebra's
device.pnp_option) — a ZPL job through a CPCL driver prints
nothing, or prints the commands as text. Not sure which language a file
is in? The language detector
reads the code itself; the CPCL hub and the
ZPL hub collect each language's tools and references.
^LL/^PQ pair has no CPCL counterpart to
translate into; both become fields of the ! line.See both engines side by side: the ZPL viewer and the CPCL viewer. If you are not sure which language a file is written in, the language detector classifies it from the code itself. Debugging specifics for the mobile side are in previewing and debugging CPCL; every CPCL command the preview reads, with its support status, is in the CPCL command reference.
ZPL, unless the printer is a mobile unit that only speaks CPCL. Zebra keeps adding features to ZPL and ships it on nearly every model; CPCL is for belt printers (ZQ/QLn) driven directly by an app, or an existing CPCL code base.
Many Link-OS mobile printers can, but only one at a time: the active language is the device.languages setting. Query it with ! U1 getvar "device.languages" and switch with ! U1 setvar "device.languages" "zpl" followed by a reset. Desk and industrial printers are ZPL-only.
The printer is in CPCL or line-print mode, so ^XA…^XZ is not parsed. Switch device.languages to zpl, and if you print through a Windows driver, set the driver to the same language (device.pnp_option).
Moving from EPL printers to TSC hardware: what the two languages share, what has no counterpart, and how to test the migration.
ZPL vs TSPL: what actually differsLabel size in dots versus real units, job structure, text and barcode syntax — the ZPL and TSPL differences that actually cost porting time.
Previewing and debugging EPL without a printerLegacy EPL/EPL2 jobs, rendered in the browser: what each line does, which findings matter, and what a preview will not draw.
Arabic text prints reversed or broken in CPCLArabic or Hebrew sent with CPCL TEXT can print reversed or with disconnected letters. Why it happens and three ways to print right-to-left text.