Schneller lokaler Zebra/ZPL-Etikettendrucker — DE + EN UI. Fast local Zebra/ZPL label tool — DE + EN UI.
Lightweight desktop utility for creating, previewing, copying, exporting, and printing simple Zebra/ZPL labels. Built for technicians and labs that need a label now, not after a vendor design suite reboot.
Zebra printers and ZPL are great. Vendor design suites are heavyweight. Workshop, lab, IT, storage, and production work usually just needs:
- pick a label size and DPI,
- type one or more printed lines (Enter = new line, never accidental print),
- choose a workflow mode (Text · Text + Code · Code only · Number sequence · Batch),
- tune what is actually needed,
- preview live — preview uses the same layout calculation as the generated ZPL,
- print with Ctrl+P or copy the ZPL.
That is the entire loop. Anything advanced lives in dropdown menus.
- Workflow modes: Text · Text + Code · Code only + caption · Number sequence · Number sequence + Code · Batch labels
- Built-in label presets: device label, asset tag, QR device link, Wi-Fi QR, part number, retail EAN-13, storage bin, cable marker
- Live preview using the exact same geometry engine that produces the ZPL — what you see is what prints
- Linear barcodes: Code 128, Code 39, EAN-13, UPC-A (real encoded preview)
- 2D codes: QR Code (real preview when
qrcodeinstalled), Data Matrix, PDF417 (deterministic layout previews — printer firmware renders the final code) - Side-by-side layouts: place barcode/QR above, below, left, right, or centered
- Text controls: font size slider, alignment, rotation, line gap, offsets, auto-fit, font style, case transforms, whitespace cleanup, line wrap
- Numbered series: ranges, padding, prefix/suffix, text templates, per-label barcode/QR payloads
- Batch labels: paste blocks of text and generate one ZPL stream
- ZPL tools: copy, export
.zpl, import simple.zplfiles generated by this tool, show ZPL window - Direct Windows RAW printing via
pywin32 - Doctor command to verify the local environment
- Two UIs:
- Python CustomTkinter desktop (stable baseline,
python main.py) - Tauri WebView client (modern UI direction,
desktop/)
- Python CustomTkinter desktop (stable baseline,
- DE + EN UI with first-start language picker and persistent setting
- Keyboard-first workflow — see shortcuts below
- CLI mode for generating ZPL without launching the GUI
You do not need Python, Node, or Rust to use the tool.
- Open the Releases page.
- Download
ZebraLabelTool.exefrom the latest release. - Double-click it. The first launch asks for Deutsch / English and remembers your choice.
- Add the file to your Desktop or pin it to Start for one-click access.
It is a single-file executable (no installer, no admin rights). The Tauri client is also available as .msi / NSIS .exe on the same release page if you prefer an installer experience.
If the repository is checked out locally, the Start-ZebraLabelTool.bat / Start-ZebraLabelTool.ps1 launcher scripts pick the right path automatically: prebuilt .exe first, otherwise the local Python venv.
Real screenshots intentionally not committed yet. Drop verified Windows captures into docs/screenshots/:
docs/screenshots/main-window.pngdocs/screenshots/preview-example.pngdocs/screenshots/windows-printer-selection.png
git clone https://github.com/DevOpsOfChaos/zebra-label-tool.git
cd zebra-label-tool
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
python main.pypy -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -e ".[dev]"
pytest -q
python -m zebra_label_tool.doctor
python main.pyzebra-label-tool-gui # desktop UI
zebra-label-tool-doctor # environment check
zebra-label-tool "label text" # CLI ZPL generationpython -m zebra_label_tool.doctorReports Python version, GUI dependencies (customtkinter, qrcode), Windows printing (pywin32), and Tauri tooling (Node/npm/Cargo and required icon files). The doctor does not change anything on your system.
python main.pyThe first launch asks once for Deutsch / English. Change it later under Settings → Language (or Einstellungen → Sprache).
| Shortcut | Action |
|---|---|
Enter |
Add another printed text line inside the editor |
Ctrl+P |
Print current label |
Ctrl+S |
Save current settings |
Ctrl+N |
Clear and start a new label |
Ctrl+L |
Label setup |
Ctrl+T |
Text options |
Ctrl+B |
Barcode / QR options |
Ctrl+Shift+B |
Batch labels window |
Ctrl+Shift+N |
Number sequence window |
F5 |
Refresh printer list / preview |
Esc |
Close the app |
# Simple one-line label
python -m zebra_label_tool "Workshop A" --width-mm 57 --height-mm 19 --dpi 300
# Multi-line plus Code 128 barcode and border
python -m zebra_label_tool "Shelf A-12" "Box 04" --line "Batch 7" --barcode "A12-04" --border
# QR code on the right of the text
python -m zebra_label_tool "Device" "ESP32" --barcode "https://example.local/device/1" --barcode-type qr --barcode-pos right --barcode-height 120 --barcode-magnification 5
# Numbered serial labels
python -m zebra_label_tool "Asset {value}" "Rack A" --sequence-count 10 --sequence-prefix AS- --sequence-padding 4
# Text rotation/offset
python -m zebra_label_tool "Motor" "230 V" --alignment left --rotation normal --line-gap 14 --offset-x 10A second, modern WebView client lives under desktop/. It uses the same Python printing bridge under the hood.
cd desktop
npm install
npm run tauri devRequires Node.js, Rust, Microsoft C++ Build Tools, and WebView2 on Windows. Run npm run doctor first to catch missing prerequisites. Full notes: docs/TAURI_DESKTOP.md.
desktop/ # modern Tauri WebView client
src/zebra_label_tool/
app.py # CustomTkinter desktop UI (stable baseline)
barcodes.py # barcode/QR metadata, aliases, payload validation
batch.py # batch label ZPL helpers
cli.py # CLI ZPL generation
constants.py # shared UI colors, DPI presets, etc.
doctor.py # environment health check
i18n.py # built-in English/German translation registry
label_spec.py # validated label request model
layout.py # pure label geometry/layout calculations
number_sequences.py # numbered series helpers
presets.py # built-in workflow presets
preview.py # canvas preview (uses layout.py)
preview_symbols.py # local barcode/QR preview patterns
printing.py # Windows RAW printing backend
settings.py # per-user settings persistence
text_tools.py # editor cleanup/wrapping helpers
zpl.py # pure ZPL generation
zpl_import.py # simple .zpl import
tests/ # core regression tests (no GUI)
docs/ # screenshots + Tauri notes
.github/ # CI, issue templates
The ZPL/layout modules stay GUI-free and printer-free. This is the main extension point.
- All UI strings live in
src/zebra_label_tool/i18n.pyas a flat key registry with full DE/EN parity (also covers the Tauri client viadesktop/src/i18n.ts). - First launch asks once which language to use. The choice is saved to
settings.json. - Switch later via
Settings → Language(Python UI) or the language switcher in the Tauri header. - Adding a new language = add another dictionary in
i18n.py; the renderer falls back to English for missing keys.
Near-term
- Real Windows screenshots in
docs/screenshots/ - Packaged Windows release build (PyInstaller)
- Network printer backend (TCP 9100)
- Batch preview + CSV import
- Visual polish after real Windows review of the Tauri client
Later
- More barcode tuning options and scanner-oriented validation
- Template sharing / export
- User-editable template variables
- Additional UI languages through the translation registry
python -m compileall .
pytest -qpytest -q runs the full core suite. The GUI is not unit-tested directly; instead, tests/test_gui_shortcuts_source.py keeps the menu shortcut wiring honest.
pip install pyinstaller
pyinstaller ZebraLabelTool.spec --clean --noconfirmOutput: dist/ZebraLabelTool.exe (single-file, windowed, ~14 MB). The spec bundles CustomTkinter themes, the qrcode encoding tables, and uses desktop/src-tauri/icons/icon.ico for the binary icon. UPX compression is intentionally disabled to reduce Windows SmartScreen / antivirus false-positives.
cd desktop
npm ci
npm run tauri buildOutput lands in desktop/src-tauri/target/release/bundle/ (.msi and NSIS .exe). Requires Rust + MSVC Build Tools + WebView2 + Node.js. Run npm run doctor first.
Pushing a tag named v* triggers .github/workflows/release.yml, which:
- builds
dist/ZebraLabelTool.exevia PyInstaller onwindows-latest, - builds the Tauri
.msi/ NSIS.exe(best-effort, does not block the release on Tauri failures), - attaches every artifact to the matching GitHub Release with auto-generated notes.
To cut a release manually:
git tag v0.2.0
git push origin v0.2.0Small, focused pull requests are welcome. Good first contributions:
- add tests for new ZPL output variants,
- improve docs / add real screenshots,
- add label presets,
- improve error messages,
- add printer backend implementations without touching the ZPL core,
- add another UI language to
i18n.py/desktop/src/i18n.ts.
See CONTRIBUTING.md for the local setup and pre-PR checks. See SECURITY.md for what not to put into public issues (private printer names, internal hostnames, etc).
MIT. See LICENSE.