README.md

April 27, 2026 ยท View on GitHub

๐Ÿ–จ๏ธ thermoprint

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.

Marklife P15 Marklife P12 Marklife P7 L11 Compatible

๐ŸŒ Web Editor โ€ข Features โ€ข Packages โ€ข Quick Start โ€ข Printers โ€ข Architecture โ€ข Sponsor

Sponsor Web Editor Version License Bun TypeScript Platform


Features

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

Packages

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)
PackageDescriptionTransport
@thermoprint/coreShared library โ€” protocol, imaging, profilesAny BleTransport
@thermoprint/cliTerminal interfaceNoble (Node/Bun)
@thermoprint/webBrowser label editorWeb Bluetooth API

Quick Start

Web Editor (no install needed)

Open tomladder.github.io/thermoprint in Chrome or Edge, connect your printer via Bluetooth, design a label, and print.

CLI

# 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.png

From Release Binaries

Pre-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

CLI Commands

CommandDescription
thermoprint discoverFind nearby Bluetooth printers
thermoprint print <image>Print an image file
thermoprint statusShow battery level and printer status
thermoprint config getShow current configuration
thermoprint config set <key> <value>Update a setting
OptionDescription
--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)

Supported Printers

Works out of the box with these Bluetooth thermal label printers:

ModelProtocolPrint WidthStatus
Marklife P15L11384 px (48 mm)โœ… Fully supported
Marklife P12L11384 px (48 mm)โœ… Fully supported
Marklife P7L11384 px (48 mm)โœ… Fully supported
Other L11-compatibleL11VariesShould 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.


Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            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.


Using the Core Library

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();

Development

# 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

Documentation


FAQ

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.


Tech Stack


Support the Project

All sponsorship money goes directly toward buying more thermal printers so they can be reverse-engineered and supported in thermoprint. Every new printer means broader compatibility for everyone.

If you find thermoprint useful, consider sponsoring the project โ€” your contribution helps grow the list of supported printers.


License

This project is licensed under the MIT License โ€” see the LICENSE file for details.


Made with ๐Ÿ–จ๏ธ and TypeScript