Skip to content

tomLadder/thermoprint

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ–¨οΈ 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

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

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

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

Print Options

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)

Supported Printers

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.


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


License

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


Made with πŸ–¨οΈ and TypeScript

About

πŸ–¨οΈ Design and print labels for Marklife P15, P12, P7 and other Bluetooth thermal printers. Visual drag-and-drop label editor in the browser, CLI for terminal printing, and a platform-agnostic TypeScript core. Supports text, images, QR codes, barcodes. No server needed.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages