LabelCut
Cuts a full-page shipping label down to the label size your printer reports.
A carrier gives you a whole Letter or A4 page with the label somewhere on it; a label printer wants just the label, at its own size. LabelCut finds the label, lets you fix the crop, sizes the page to the paper the printer reports and prints through the host's CUPS.
Pick a paper below: the sample label comes out on it at true scale, laid out by LabelCut's own steps re-run in your browser. The printer is a stand-in; none was attached when this was built.
Self-hosted for a home network. Version 0.1.0, May to October 2026, 24 commits, one author.
Where the size comes from
- Your choiceNone
- Fallback in settings4 × 6
You left it to the printer, so its default, 4 × 6, wins.
Layout
Finding the label
It takes a PDF or an image (11 file extensions, HEIC included) up to 50 MB by default, or a file from a saved-label folder on the host.
Then it looks for the label with a deliberately simple rule, not machine learning: anything darker than near-white is ink, nearby ink is merged, small specks are dropped, and the boxes are joined into one, padded by a margin and widened to the label's shape. On a page with no ink it falls back to a centred box.
The crop editor
When the guess is off, you fix it by hand. The editor was built from scratch, without a crop library: eight handles, draw a new box, move it, lock its shape, zoom from 100 to 300%, type X, Y, W and H, nudge with the arrow keys, and see how much of the page the crop covers. Rotating the page carries the crop along instead of resetting it.


The paper the printer reports
The output is a 300 DPI page at the paper's physical size. The size you pick beats the printer's own default, which beats the fallback in settings. Both the browser and the server can read the printer's size names (18 on the server, 17 in the browser), so the preview knows the size before the server confirms it.
Every edit regenerates the preview after 350 ms, and an older response can never overwrite a newer edit; four of the seven frontend tests check exactly that. The printer above waits the same 350 ms.

Printing without a shell
It prints through the host's CUPS. It calls CUPS's own tools with a checked list of arguments, never through a shell, checks every printer option against a strict pattern, and shows the exact result, exit code and output included. When CUPS isn't running, the printer panel says so plainly, as its own state, not as a failed print.

Hardening and tests
In October 2026, eight tracker issues tightened it:
- A 20-million-pixel budget, checked before any image is decoded or allocated.
- Label sides capped at 40 in.
- Print files picked only by ID, never by a path outside storage.
- Only the app's own hosts accepted.
- The backend reachable only through the front end.
- A memory cap of 1 GB.
The same budget turns down one label scaled to 200% on Letter, on the printer above.
68 backend and 7 frontend tests pass. CUPS is mocked, so no test prints for real. There is no CI.
Limits
The detector is a simple threshold-and-box rule. It doesn't read barcodes or text.
It's LAN-only, with no sign-in: the network is the only access control.
The repo has no record of a printed label. It shows the app was used on real labels, not that they printed.
Built with FastAPI, OpenCV, PyMuPDF and Pillow; React 19 and Vite; Docker Compose with nginx; and the host's CUPS.