Zebra labels, written in TypeScript
node-zpl builds ZPL from typed code or JSX, checks it for mistakes the printer won't report, and shows you the label before anything is printed.
npm install node-zplconst label = build(
<Label width={mm(101.6)} height={mm(50.8)} dpmm={8}>
<Text x={mm(5)} y={mm(5)} height={mm(7)}>
Harbor Parts Co.
</Text>
<Text x={mm(5)} y={mm(14)} height={mm(4)}>
Order #{order.id} · Shelf {order.shelf}
</Text>
<Box x={mm(5)} y={mm(21)} width={mm(91)}
height={dots(3)} thickness={dots(3)} />
<Code128 x={mm(5)} y={mm(25)} height={mm(13)}>
{`${order.id}-${order.shelf}`}
</Code128>
<DataMatrix x={mm(76)} y={mm(25)} moduleSize={dots(5)}>
https://zpl.fingal.dev
</DataMatrix>
{order.express && (
<Text x={mm(66)} y={mm(5)} height={mm(7)}>EXPRESS</Text>
)}
</Label>
);
label.toZPL();102030405060708090100
101.6 × 50.8 mm
Build labels with types
Write labels as JSX or method calls. Every length takes a unit, mm() or dots(), so a bare number is a type error, and text is escaped for you.
<Text x={mm(5)} y={mm(5)}>
Hello
</Text>Catch what the printer won't tell you
Printers quietly clamp values, ignore commands and skip fields. The linter finds those problems in labels you build and in ZPL you already have.
lint(parse(zpl).commands);
// The box is 1 dot wide but its
// line is 2 dots thick, so the
// printer widens it to 2 dots.Preview anywhere
A web component renders labels in the browser for React, Vue, Svelte, Angular or plain HTML. Label data never leaves the page.
<zpl-preview
zpl={label}
dpmm={8}
/>