Print labels on an Epson LabelWorks LW-600P from macOS over USB, without the Epson driver
  • Go 85.2%
  • JavaScript 7.2%
  • HTML 4.2%
  • CSS 3.4%
Find a file
Hans Hübner 841b84ae98 Print labels on an Epson LW-600P over USB
Talk to the printer's ESCPL2 language directly over libusb, since the CUPS
usb backend on current macOS no longer loads the vendor's USB print-class
plugin.

The core reads the installed cartridge from a vendor control transfer, which
also carries the activity flag used to wait for a job to finish. Jobs carry a
cut policy that makes the printer discard the blank tape ahead of the print,
so a label starts at its cut edge, and a run of labels prints as one job that
pays for that leader once.

Measured on the printer: the head resolves 180 dpi across the tape while the
tape advances about 0.136 mm per raster record, so label pixels are not
square. The calibration profile carries the measured feed scale, and text is
drawn at a square resolution and resampled onto the dot grid to keep glyph
shapes right. Codes are composited at final resolution instead, so module
edges land on dot boundaries, and a matrix code too small to scan is refused.

A CLI covers text, codes, images, stored templates and CSV runs. The editor
serves a local page whose preview is rendered by the same code that feeds the
printer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 08:56:24 +02:00
cmd/labeler Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00
internal Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00
.gitignore Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00
DESIGN.md Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00
go.mod Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00
go.sum Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00
README.md Print labels on an Epson LW-600P over USB 2026-08-26 08:56:24 +02:00

labeler

Print labels on an Epson LabelWorks LW-600P from macOS, over USB, without the Epson driver.

Epson's own stack no longer prints on current macOS: the CUPS usb backend stopped loading third-party USB print-class plugins, and LWUSBPrintClass.plugin is one. This talks to the printer's ESCPL2 language directly instead.

go build -o labeler ./cmd/labeler

./labeler status                          # 12 mm tape, ready
./labeler print "Rack A / Port 12"
./labeler edit                            # editor at http://127.0.0.1:8474/

What it does

  • Senses the tape. Every print reads the installed cartridge and refuses a label too tall for it.
  • Trims the leader. The printer's own cut policy discards the blank tape ahead of the print, so a label begins at its cut edge.
  • Prints a run as one job. A batch pays for the leader once, however many labels it carries.
  • Fits the type to the tape, with any installed font.
  • Draws codes that scan. QR, Data Matrix, Aztec, PDF417 and the common linear symbologies, refused rather than printed when the tape is too narrow for a readable module.

Commands

labeler status                             tape width and ready state
labeler probe                              descriptors and raw status
labeler print "Rack A / Port 12"           one label
labeler print -code qr -code-data URL TEXT a code beside the text
labeler print -image logo.png              a picture, dithered to the tape
labeler print -template rack -set port=12  a stored layout, filled in
labeler batch -template rack -csv rows.csv one label per row, as one job
labeler templates [-save NAME ...]         list or store layouts
labeler calibrate [-measured MM]           measure the feed scale
labeler feed [-cut]
labeler edit                               the editor, in a browser

Add -dry-run FILE to write the printer stream to a file instead of printing, and -preview FILE.png to save what the label will look like.

Templates

A template is a label with {field} placeholders, stored by name:

labeler templates -save rack -bold \
  -code qr -code-data 'https://inv.local/{asset}' '{rack} / Port {port}'

labeler print -template rack -set rack=A -set port=12 -set asset=4711
labeler batch -template rack -csv racks.csv

The CSV's header row names the columns. A placeholder with no value fails the run before any tape is spent.

Calibration

The head resolves 180 dpi across the tape, and the tape advances a shorter step than that along it, so lengths need a measured correction:

labeler calibrate                       # prints an 80 mm span
labeler calibrate -measured 77.1        # folds the measurement in

The result lives in ~/Library/Application Support/labeler/profile.json, along with the font the editor last chose, which the command line then uses as its default.

Requirements

macOS, Go, and libusb (brew install libusb). The printer connects over USB and needs no Epson software installed. A CUPS queue for the same printer must stay idle while this holds the interface.

Protocol

DESIGN.md records the ESCPL2 command set, the status and tape-sensing requests, the cut model, and what was measured on hardware.