MakeZPL

Guide

How to create a ZPL label, step by step

We will build one real label — a 4 × 2 inch product label with a wrapped description, a Code 128 barcode and a QR code — from an empty format to a printable file, then turn it into a reusable template. Every step shows the complete ZPL, so you can paste any of them into a printer or into the designer and see exactly that.

Follow along in the designer Command reference

Seven steps to a printable label

Written for a 203 dpi printer. On a 300 dpi machine multiply every number below by 1.5, and on a 600 dpi machine by three.

  1. Set the label size in dots

    ZPL has no idea what an inch is — it thinks in printer dots. Multiply the physical size by the print resolution and declare both with ^PW and ^LL. A 4 × 2 inch label on a 203 dpi printer is 812 × 406 dots.

    ^XA
    ^CI28
    ^PW812
    ^LL406
    ^LH0,0
    ^XZ

    ^CI28 switches the printer to UTF-8 — include it on every label unless you are certain your text is pure ASCII. ^LH0,0 puts the origin in the top-left corner.

  2. Put the first line of text on it

    A field is three commands: where it goes, what it is, and what it says. Font 0 is the scalable built-in, and its height is in dots — 44 dots is about 5.5 mm at 203 dpi.

    ^XA
    ^CI28
    ^PW812
    ^LL406
    ^LH0,0
    
    ^FO30,28^A0N,44,44^FDHEX BOLT M12 x 60^FS
    ^XZ
  3. Wrap the long description

    Plain ^FD prints one line that runs straight off the label edge. Add ^FB to give the text a width and a line limit and the printer wraps it for you.

    ^XA
    ^CI28
    ^PW812
    ^LL406
    ^LH0,0
    
    ^FO30,28^A0N,44,44^FDHEX BOLT M12 x 60^FS
    
    ^FO30,86
    ^A0N,28,28
    ^FB500,2,0,L,0
    ^FDZinc plated, grade 8.8, DIN 931 partially threaded^FS
    ^XZ

    The parameters are width in dots, maximum lines, extra line spacing, alignment and hanging indent. Text past the line limit is dropped by the printer without warning, so give it more room than you think you need.

  4. Add the barcode

    ^BY sets the narrow bar width; ^BC makes it Code 128. Both matter: at 203 dpi a narrow bar below 2 dots will not scan reliably.

    ^XA
    ^CI28
    ^PW812
    ^LL406
    ^LH0,0
    
    ^FO30,28^A0N,44,44^FDHEX BOLT M12 x 60^FS
    
    ^FO30,86
    ^A0N,28,28
    ^FB500,2,0,L,0
    ^FDZinc plated, grade 8.8, DIN 931 partially threaded^FS
    
    ^FO30,180^BY3,2,120
    ^BCN,120,Y,N,N
    ^FD4125500001^FS
    ^XZ

    Y in the third position prints the human-readable number underneath. Leave at least 30 dots of blank label at each end of the code — that quiet zone is part of the barcode, even though nothing is printed there.

  5. Add rules, a box and a QR code

    There is no line command in ZPL: a rule is a ^GB box whose thickness equals its height. A QR code is ^BQ, with the error-correction level carried at the front of the data.

    ^XA
    ^CI28
    ^PW812
    ^LL406
    ^LH0,0
    
    ^FO30,28^A0N,44,44^FDHEX BOLT M12 x 60^FS
    
    ^FO30,86
    ^A0N,28,28
    ^FB500,2,0,L,0
    ^FDZinc plated, grade 8.8, DIN 931 partially threaded^FS
    
    ^FO30,160^GB752,3,3^FS
    
    ^FO30,180^BY3,2,120
    ^BCN,120,Y,N,N
    ^FD4125500001^FS
    
    ^FO30,330^A0N,26,26^FDITEM 41255-A - BIN C-14 - QTY 250^FS
    
    ^FO600,190^BQN,2,5
    ^FDQA,41255-A^FS
    ^XZ
  6. Turn the fixed values into merge fields

    A label is only worth building once. Replace the values that change per item with placeholder tokens and you have a template your host system can fill in — MakeZPL reads these back as bound fields if you ever import the file again.

    ^XA
    ^CI28
    ^PW812
    ^LL406
    ^LH0,0
    
    ^FO30,28^A0N,44,44^FD{{item_name}}^FS
    
    ^FO30,86
    ^A0N,28,28
    ^FB500,2,0,L,0
    ^FD{{item_description}}^FS
    
    ^FO30,160^GB752,3,3^FS
    
    ^FO30,180^BY3,2,120
    ^BCN,120,Y,N,N
    ^FD{{barcode}}^FS
    
    ^FO30,330^A0N,26,26^FDITEM {{item_number}} - QTY {{quantity}}^FS
    
    ^FO600,190^BQN,2,5
    ^FDQA,{{item_number}}^FS
    ^XZ

    If instead you want the values baked in — because you are printing today, from a spreadsheet — import the data in MakeZPL and export resolved ZPL, which substitutes the values and re-fits the text for each record.

  7. Print settings, then send it

    Quantity, darkness and speed are label-level settings. Darkness in particular is worth tuning: too high and barcodes fatten until they stop scanning.

    ^MD4
    ^PR4
    ^PQ2

    Put these inside the ^XA^XZ block. Then send the file to the printer — a raw TCP connection to port 9100, a printer share, or whatever your host system already uses. ZPL is plain text; nothing needs to interpret it on the way.

Questions people hit on their first label

Sending files, positioning commands and truncated text.

Do I have to write ZPL by hand?

No — MakeZPL generates it from a canvas, and you can watch the code appear as you drag. Knowing the shape of the language is still worth an hour, because it is what you will be reading when a label misbehaves in production.

How do I send ZPL to the printer?

ZPL is plain text sent straight to the printer, so anything that can write bytes to it works: a raw TCP socket on port 9100, a Windows printer share with the driver in pass-through mode, a USB or serial connection, or your host system's own print service.

What is the difference between ^FO and ^FT?

^FO positions the top-left corner of the field; ^FT positions the text baseline. ^FO is easier to reason about and is what MakeZPL writes. If you import a label built with ^FT, the text may sit a few dots off until you nudge it.

Why is my text cut off?

Either it ran past the edge of the label, or it exceeded the line limit in its ^FB block. The printer silently drops both. MakeZPL measures the text before export and raises an overflow warning or a blocking error instead.