A wrong barcode is invisible until product is on a shelf. It looks fine on screen, it looks fine on the proof, and then a scanner at retail reads the wrong number and you’re paying for a reprint and an apology.
At Every Man Jack, barcode requests used to mean one of two things: someone pastes a number into a free web generator and gets back a raster PNG in RGB, or the request lands on whoever owns the real barcode software. The first option is exactly what a printer’s prepress team does not want. The second is a bottleneck for what should be a thirty-second task.
So Claude and I built a skill for it. Anyone on the team can now type “make me a barcode for 810202752313” into Claude and get back a GS1-compliant UPC-A as a true vector PDF: CMYK at 100% K only, digits converted to outlines so there’s no font-substitution risk at the printer, nominal 0.330 mm X-dimension, quiet zones included in the crop. It’s the file you’d hand a packaging vendor, produced by asking in plain English.
Under the hood it’s BWIPP, the reference barcode implementation written in pure PostScript, driven through Ghostscript. Both stages are vector, so nothing is ever rasterized. No network calls, no barcode SaaS subscription. The whole encoder is a 27 KB PostScript file bundled inside the skill.
The part I actually care about is the self-check. After writing each PDF, the script reads the file back, parses the raw vector geometry out of the page content stream, reconstructs the 95-module bar pattern, and decodes it to digits with its own independent decoder:
left = bars[0][0]right = bars[-1][0] + bars[-1][1]module = (right - left) / 95.0 # UPC-A is exactly 95 modules
grid = ["0"] * 95for bx, bw, _ in bars: start = round((bx - left) / module) for i in range(start, start + max(1, round(bw / module))): grid[i] = "1"If the decoded digits don’t match what was requested, the file is deleted and the run fails loudly:
elif decoded != digits: os.remove(output) raise BarcodeError( f"SELF-CHECK FAILED: generated file decodes to {decoded}, " f"expected {digits}. File deleted rather than risk bad artwork." )That’s the whole trust model. I’m comfortable letting an AI produce printer-bound artwork because the artifact proves itself before anyone sees it. The skill’s instructions push the same paranoia onto Claude: check digits are arithmetic, not a database lookup, so a 12-digit input with a bad final digit gets refused with the correct one suggested. Asked for an EAN-13 or a case code? The skill says so plainly instead of generating something wrong-but-plausible.
The barcode is honestly the least interesting part. The pattern is the point: take a task with real prepress rules, freeze the rules into a script, wrap it in a skill so the interface is a sentence, and make the output verify itself. That combination is what lets you hand it to the whole team and stop thinking about it.
BWIPP quietly applies 0.15 modules of bar width reduction by default, by the way. Found that one the hard way, which is what the verifier is for.