Design and print labels on Marklife P15, P12, P7 and other Bluetooth thermal printers
Visual label editor in the browser, powerful CLI for automation and AI agents, and a platform-agnostic TypeScript core.
No server required β everything runs locally via Web Bluetooth or Noble.
π Web Editor β’ Features β’ Packages β’ Quick Start β’ Printers β’ Architecture
Web Editor β try it now
- Drag & drop label designer with text, images, QR codes, barcodes, and shapes
- Resize, rotate, and align elements visually on a Konva.js canvas
- Live-preview with gap/continuous paper simulation and ghost labels
- Print directly from the browser via Web Bluetooth (Chrome/Edge)
- Save & load templates, dark mode, responsive layout
CLI
- Discover nearby printers over Bluetooth
- Print images and labels from the terminal
- Check battery and printer status
- Configure label size, density, dithering
Core Library
- Platform-agnostic β inject any
BleTransport(Noble, Web Bluetooth, etc.) - Full image pipeline: RGBA β grayscale β Floyd-Steinberg dither β 1-bit raster
- Credit-based flow control prevents printer buffer overflow
- Device profiles for easy printer support
thermoprint/
packages/
core/ @thermoprint/core β protocol, image pipeline, device profiles
cli/ @thermoprint/cli β command-line interface (Noble + sharp)
web/ @thermoprint/web β visual label editor (React + Konva.js)
| Package | Description | Transport |
|---|---|---|
@thermoprint/core |
Shared library β protocol, imaging, profiles | Any BleTransport |
@thermoprint/cli |
Terminal interface | Noble (Node/Bun) |
@thermoprint/web |
Browser label editor | Web Bluetooth API |
Open tomladder.github.io/thermoprint in Chrome or Edge, connect your printer via Bluetooth, design a label, and print.
# Clone & install
git clone https://github.com/tomLadder/thermoprint.git && cd thermoprint
bun install
# Discover printers (requires Bluetooth)
bun run packages/cli/src/index.ts discover
# Print an image
bun run packages/cli/src/index.ts print my-label.pngPre-built binaries for macOS, Linux, and Windows are available on the Releases page.
# macOS / Linux
thermoprint discover
thermoprint print label.png
# Check status
thermoprint status| Command | Description |
|---|---|
thermoprint discover |
Find nearby Bluetooth printers |
thermoprint print <image> |
Print an image file |
thermoprint status |
Show battery level and printer status |
thermoprint config get |
Show current configuration |
thermoprint config set <key> <value> |
Update a setting |
| Option | Description |
|---|---|
--density <1|2|3> |
Print darkness (1=light, 2=normal, 3=dark) |
--paper <gap|continuous> |
Paper type |
--dither <floyd-steinberg|threshold|none> |
Dithering algorithm |
--threshold <0-255> |
Black/white cutoff for threshold mode |
--width <px> |
Print head width (default: 384) |
Works out of the box with these Bluetooth thermal label printers:
| Model | Protocol | Print Width | Status |
|---|---|---|---|
| Marklife P15 | L11 | 384 px (48 mm) | β Fully supported |
| Marklife P12 | L11 | 384 px (48 mm) | β Fully supported |
| Marklife P7 | L11 | 384 px (48 mm) | β Fully supported |
| Other L11-compatible | L11 | Varies | Should work |
Have a different printer? Any label printer using the L11 protocol should work. Adding a new printer is just a device profile β a plain object with BLE service/characteristic UUIDs and settings.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web Editor (React + Konva.js) β
β Toolbar β Canvas β Export β Print via Web Bluetooth β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β CLI (Commander + Chalk + Ora) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Printer Orchestrator (Core) β
β connect Β· print Β· events Β· discovery β
ββββββββββββ¬βββββββββββββββ¬ββββββββββββββββββββββββββββββββ€
β Image β Protocol β Device β
β Pipeline β (L11) β Registry β
ββββββββββββ΄βββββββββββββββ΄ββββββββββββββββββββββββββββββββ€
β FlowController β
β Credit-based BLE chunking β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β BleTransport (injected) β
β Noble Β· Web Bluetooth Β· custom β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Image pipeline: RGBA β grayscale β Floyd-Steinberg dither β 1-bit pack β raster commands
Flow control: Credit-based backpressure prevents buffer overflow. The host waits for credit grants before sending each chunk.
Protocol: L11 is a binary raster protocol. The printer has no built-in fonts β all content is rendered to a bitmap before sending.
import { Printer, discover } from "@thermoprint/core";
const transport = new MyBleTransport();
const peripheral = await discover(transport, { timeoutMs: 5000 });
const printer = await Printer.connect(transport, peripheral);
await printer.print(myImageData, {
density: 2,
paperType: "gap",
dither: "floyd-steinberg",
});
await printer.disconnect();# Clone
git clone https://github.com/tomLadder/thermoprint.git && cd thermoprint
# Install dependencies
bun install
# Run the web editor locally
bun run --cwd packages/web dev
# Run CLI commands
bun run packages/cli/src/index.ts --help- Architecture β design decisions, layer diagram, data flow
- Transport β BleTransport interface and flow control
- Image Pipeline β grayscale, dithering, bit packing
- Adding a Printer β how to add a new device profile
- Reverse Engineering β protocol analysis from the Android app
Which browsers support Web Bluetooth?
Chrome and Edge on desktop (macOS, Windows, Linux, ChromeOS). Safari and Firefox do not support Web Bluetooth. On mobile, Chrome on Android works.
Why does the printer need to be "discovered" each time?
Web Bluetooth requires a user gesture (click) to initiate device pairing via the browser's device picker. This is a security requirement β there's no background scanning in browsers.
Can I add support for my printer?
If your printer uses the L11 protocol (common for small Bluetooth label printers), it likely works already. Otherwise, create a device profile with your printer's BLE service/characteristic UUIDs and settings.
Why are printed images rotated?
The printer feeds paper lengthwise, so the image is rotated 90Β° before printing. The editor handles this automatically β what you see is what you get.
- Runtime: Bun
- Language: TypeScript (strict, ESNext)
- Web: React 19 + Konva.js + Zustand + Tailwind CSS 4
- BLE: @stoprocent/noble (CLI), Web Bluetooth API (Web)
- Image: sharp (CLI), Canvas API (Web)
- CLI: Commander.js + Chalk + Ora
This project is licensed under the MIT License β see the LICENSE file for details.
Made with π¨οΈ and TypeScript