Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/mirror.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ jobs:
# Mirror exactly the ref that triggered (checkout only fetches that one);
# never --mirror, which would force-push and DELETE unknown refs.
- if: steps.token.outputs.have == 'true'
run: git push --force "https://u8array:${{ secrets.CODEBERG_TOKEN }}@codeberg.org/u8array/ZebraPrintLab.git" "HEAD:${{ github.ref }}"
run: git push --force "https://u8array:${{ secrets.CODEBERG_TOKEN }}@codeberg.org/u8array/ZPLab.git" "HEAD:${{ github.ref }}"
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# ZebraPrintLab
# ZPLab

<img src="public/favicon.png" alt="Zebra Print Lab logo" width="64" align="right" />
<img src="public/favicon.png" alt="ZPLab logo" width="64" align="right" />

[![Deploy](https://github.com/u8array/ZebraPrintLab/actions/workflows/deploy.yml/badge.svg?branch=prod)](https://github.com/u8array/ZebraPrintLab/actions/workflows/deploy.yml?query=branch%3Aprod)
[![CI](https://github.com/u8array/ZebraPrintLab/actions/workflows/pr.yml/badge.svg)](https://github.com/u8array/ZebraPrintLab/actions/workflows/pr.yml)
[![Deploy](https://github.com/u8array/ZPLab/actions/workflows/deploy.yml/badge.svg?branch=prod)](https://github.com/u8array/ZPLab/actions/workflows/deploy.yml?query=branch%3Aprod)
[![CI](https://github.com/u8array/ZPLab/actions/workflows/pr.yml/badge.svg)](https://github.com/u8array/ZPLab/actions/workflows/pr.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

A browser-based ZPL editor for Zebra printers: design labels visually, or import existing ZPL, edit it, and re-export it byte-for-byte.

Writing ZPL (Zebra Programming Language) by hand is tedious: cryptic commands, dot coordinates, no visual feedback until something comes out of the printer. Zebra Print Lab lets you build labels visually instead. Drag elements onto the canvas, tweak them in the properties panel, then copy or download the ZPL. No installation, no ZPL knowledge required.
Writing ZPL (Zebra Programming Language) by hand is tedious: cryptic commands, dot coordinates, no visual feedback until something comes out of the printer. ZPLab lets you build labels visually instead. Drag elements onto the canvas, tweak them in the properties panel, then copy or download the ZPL. No installation, no ZPL knowledge required.

Existing ZPL files are a first-class source, not a one-way import: a re-exported label stays byte-for-byte identical except for the objects you actually edited (see [Import guarantees](#import-guarantees)); GS1 and EAN/UPC content is validated field by field.

**[Try it](https://zebraprintlab.org/)** · [Download the desktop app](#download) · [Report an issue](https://github.com/u8array/ZebraPrintLab/issues)
**[Try it](https://zebraprintlab.org/)** · [Download the desktop app](#download) · [Report an issue](https://github.com/u8array/ZPLab/issues)

> **Disclaimer:** This is an independent open-source tool, not affiliated with, endorsed by, or associated with Zebra Technologies Corp. Zebra is a trademark of Zebra Technologies Corp.; all other trademarks are the property of their respective owners.

Expand All @@ -21,18 +21,18 @@ Existing ZPL files are a first-class source, not a one-way import: a re-exported
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshot-dark.png">
<source media="(prefers-color-scheme: light)" srcset="docs/screenshot-light.png">
<img alt="Zebra Print Lab: designer with a sample label" src="docs/screenshot-light.png">
<img alt="ZPLab: designer with a sample label" src="docs/screenshot-light.png">
</picture>

---

## Download

| Platform | [v0.1.0](https://github.com/u8array/ZebraPrintLab/releases/tag/v0.1.0) (pre-release) |
| Platform | [v0.1.0](https://github.com/u8array/ZPLab/releases/tag/v0.1.0) (pre-release) |
|---|---|
| Windows | [x64 installer](https://github.com/u8array/ZebraPrintLab/releases/download/v0.1.0/ZPLab_0.1.0_x64-setup.exe) |
| macOS | [Apple Silicon](https://github.com/u8array/ZebraPrintLab/releases/download/v0.1.0/ZPLab_0.1.0_aarch64.dmg) · [Intel](https://github.com/u8array/ZebraPrintLab/releases/download/v0.1.0/ZPLab_0.1.0_x64.dmg) |
| Linux | [AppImage](https://github.com/u8array/ZebraPrintLab/releases/download/v0.1.0/ZPLab_0.1.0_amd64.AppImage) · [deb](https://github.com/u8array/ZebraPrintLab/releases/download/v0.1.0/ZPLab_0.1.0_amd64.deb) · [rpm](https://github.com/u8array/ZebraPrintLab/releases/download/v0.1.0/ZPLab-0.1.0-1.x86_64.rpm) |
| Windows | [x64 installer](https://github.com/u8array/ZPLab/releases/download/v0.1.0/ZPLab_0.1.0_x64-setup.exe) |
| macOS | [Apple Silicon](https://github.com/u8array/ZPLab/releases/download/v0.1.0/ZPLab_0.1.0_aarch64.dmg) · [Intel](https://github.com/u8array/ZPLab/releases/download/v0.1.0/ZPLab_0.1.0_x64.dmg) |
| Linux | [AppImage](https://github.com/u8array/ZPLab/releases/download/v0.1.0/ZPLab_0.1.0_amd64.AppImage) · [deb](https://github.com/u8array/ZPLab/releases/download/v0.1.0/ZPLab_0.1.0_amd64.deb) · [rpm](https://github.com/u8array/ZPLab/releases/download/v0.1.0/ZPLab-0.1.0-1.x86_64.rpm) |

macOS blocks the first launch; allow the app under *System Settings > Privacy & Security*.

Expand Down
2 changes: 1 addition & 1 deletion THIRD-PARTY-LICENSES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Third-party licenses

ZebraPrintLab's own source is under the license in `LICENSE`. This file records
ZPLab's own source is under the license in `LICENSE`. This file records
third-party material redistributed in the built app (`dist/`) and its
attribution terms, and it ships in `dist/` so the notices accompany the code
and fonts they cover. The npm section is generated from the production
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "zebra-print-lab",
"name": "zplab",
"private": true,
"version": "0.1.0",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion scripts/gen-attribution.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const DATA_DIR = join(ROOT, 'scripts', 'data');

const PREAMBLE = `# Third-party licenses

ZebraPrintLab's own source is under the license in \`LICENSE\`. This file records
ZPLab's own source is under the license in \`LICENSE\`. This file records
third-party material redistributed in the built app (\`dist/\`) and its
attribution terms, and it ships in \`dist/\` so the notices accompany the code
and fonts they cover. The npm section is generated from the production
Expand Down
4 changes: 2 additions & 2 deletions scripts/lib/pnpm-licenses.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Single source for reading the production dependency license tree. Both the
// license gate and the attribution generator depend on the exact same scope:
// the shipped app only (--filter zebra-print-lab). Since the workspace split,
// the shipped app only (--filter zplab). Since the workspace split,
// an unscoped read would also pull packages/mcp-server's tree, which runs as a
// separate process and never lands in dist/.
import { execSync } from 'node:child_process';
Expand All @@ -13,7 +13,7 @@ export function readProdLicenses() {
try {
// maxBuffer well above the current ~20 KB so a growing tree can't hit the
// 1 MB default and turn a license read into an ENOBUFS crash.
raw = execSync('pnpm licenses list --prod --json --filter zebra-print-lab', { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
raw = execSync('pnpm licenses list --prod --json --filter zplab', { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 });
} catch (e) {
console.error('Could not read `pnpm licenses list --prod --json`:', e.message);
process.exit(2);
Expand Down
58 changes: 29 additions & 29 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
[package]
name = "zebra-print-lab"
name = "zplab"
version = "0.1.0"
description = "ZPLab desktop shell"
authors = ["u8array"]
license = "MIT"
repository = "https://github.com/u8array/ZebraPrintLab"
repository = "https://github.com/u8array/ZPLab"
edition = "2021"
rust-version = "1.77.2"

[lib]
name = "zebra_print_lab_lib"
name = "zplab_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/THIRD-PARTY-LICENSES-RUST.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Third-party licenses (Rust)

Licenses of the Rust crates redistributed in the ZebraPrintLab desktop app (the
Licenses of the Rust crates redistributed in the ZPLab desktop app (the
Tauri bundle). Generated from the crate dependency tree by `cargo-about` via
`src-tauri/about.hbs`; the Rust-side counterpart of `THIRD-PARTY-LICENSES.md`
(npm). A freshness gate in CI regenerates this file and fails the build if it
Expand Down Expand Up @@ -5767,7 +5767,7 @@ SOFTWARE.

Used by:

- [zebra-print-lab 0.1.0](https://github.com/u8array/ZebraPrintLab)
- [zplab 0.1.0](https://github.com/u8array/ZPLab)
- [atoi_simd 0.16.1](https://github.com/RoDmitry/atoi_simd)
- [block2 0.6.2](https://github.com/madsmtm/objc2)
- [brotli-decompressor 5.0.3](https://github.com/dropbox/rust-brotli-decompressor)
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/about.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Third-party licenses (Rust)

Licenses of the Rust crates redistributed in the ZebraPrintLab desktop app (the
Licenses of the Rust crates redistributed in the ZPLab desktop app (the
Tauri bundle). Generated from the crate dependency tree by `cargo-about` via
`src-tauri/about.hbs`; the Rust-side counterpart of `THIRD-PARTY-LICENSES.md`
(npm). A freshness gate in CI regenerates this file and fails the build if it
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"fs:allow-write-text-file",
{
"identifier": "opener:allow-open-url",
"allow": [{ "url": "https://github.com/u8array/ZebraPrintLab" }]
"allow": [{ "url": "https://github.com/u8array/ZPLab" }]
}
]
}
2 changes: 1 addition & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

fn main() {
zebra_print_lab_lib::run();
zplab_lib::run();
}
4 changes: 2 additions & 2 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYzNTVGNUIzRjVERjQyMQpSV1FoOUYwL1cxODFEMW4xcVZYZndYVWlwM3lyaGYrK3FpSWN5cjBxanM1ZDdVR3B4a3Y2Y0ZsTAo=",
"endpoints": [
"https://github.com/u8array/ZebraPrintLab/releases/latest/download/latest.json"
"https://github.com/u8array/ZPLab/releases/latest/download/latest.json"
]
}
},
Expand All @@ -42,7 +42,7 @@
"publisher": "u8array",
"copyright": "© 2026 u8array",
"license": "MIT",
"homepage": "https://github.com/u8array/ZebraPrintLab",
"homepage": "https://github.com/u8array/ZPLab",
"category": "Productivity",
"shortDescription": "ZPL label designer",
"longDescription": "Visual designer for Zebra ZPL printer labels with live preview and ZPL import/export.",
Expand Down
2 changes: 1 addition & 1 deletion src/lib/openExternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isDesktopShell } from './platform';
/** The project repository. Kept in sync with the opener capability allowlist in
* src-tauri/capabilities/default.json (opener:allow-open-url), which scopes the
* desktop opener to exactly this URL. */
export const REPO_URL = 'https://github.com/u8array/ZebraPrintLab';
export const REPO_URL = 'https://github.com/u8array/ZPLab';

/** The desktop webview sandboxes window.open, so external links route through
* the opener plugin (dynamic import keeps it out of the web bundle). */
Expand Down