|
| 1 | +# π¨οΈ thermoprint |
| 2 | + |
| 3 | +TypeScript toolkit for Bluetooth thermal printers. Discover, connect, and print from the command line or your own code. |
| 4 | + |
| 5 | +``` |
| 6 | +$ thermoprint discover |
| 7 | +Found 1 printer(s): |
| 8 | +
|
| 9 | + P15 a1b2c3d4-... RSSI: -52 Model: p15 |
| 10 | +
|
| 11 | +$ thermoprint print label.png |
| 12 | +β Print complete! |
| 13 | +``` |
| 14 | + |
| 15 | +## Supported Printers |
| 16 | + |
| 17 | +| Model | Protocol | Print Width | Status | |
| 18 | +|-------|----------|-------------|--------| |
| 19 | +| Marklife P15 | L11 | 384 px (48 mm) | Fully supported | |
| 20 | +| Marklife P12 | L11 | 384 px (48 mm) | Fully supported | |
| 21 | +| Marklife P7 | L11 | 384 px (48 mm) | Fully supported | |
| 22 | +| Other L11-compatible | L11 | Varies | Should work | |
| 23 | + |
| 24 | +Adding a new printer is just a [device profile](docs/adding-a-printer.md) β a plain object with UUIDs and settings. |
| 25 | + |
| 26 | +## Packages |
| 27 | + |
| 28 | +``` |
| 29 | +thermoprint/ |
| 30 | + packages/ |
| 31 | + core/ @thermoprint/core β protocol, image pipeline, device profiles |
| 32 | + cli/ @thermoprint/cli β command-line interface (Noble + sharp) |
| 33 | +``` |
| 34 | + |
| 35 | +### `@thermoprint/core` |
| 36 | + |
| 37 | +Platform-agnostic library. No BLE dependency β you inject a `BleTransport` for your runtime. |
| 38 | + |
| 39 | +```typescript |
| 40 | +import { Printer, discover } from "@thermoprint/core"; |
| 41 | +import { NobleBleTransport } from "./my-transport"; |
| 42 | + |
| 43 | +const transport = new NobleBleTransport(); |
| 44 | +const peripheral = await discover(transport, { timeoutMs: 5000 }); |
| 45 | +const printer = await Printer.connect(transport, peripheral); |
| 46 | + |
| 47 | +await printer.print(myImageData, { density: 2, paperType: "gap" }); |
| 48 | +await printer.disconnect(); |
| 49 | +``` |
| 50 | + |
| 51 | +### `@thermoprint/cli` |
| 52 | + |
| 53 | +Ready-to-use CLI powered by Noble and sharp. |
| 54 | + |
| 55 | +```bash |
| 56 | +thermoprint discover # Find nearby printers |
| 57 | +thermoprint print photo.png # Print an image |
| 58 | +thermoprint status # Battery + status |
| 59 | +thermoprint config set width 320 # Configure for your label size |
| 60 | +``` |
| 61 | + |
| 62 | +See the full [CLI documentation](packages/cli/README.md). |
| 63 | + |
| 64 | +## Quick Start |
| 65 | + |
| 66 | +```bash |
| 67 | +# Clone |
| 68 | +git clone <repo-url> && cd thermoprint |
| 69 | + |
| 70 | +# Install |
| 71 | +bun install |
| 72 | + |
| 73 | +# Discover printers (requires Bluetooth) |
| 74 | +bun run packages/cli/src/index.ts discover |
| 75 | + |
| 76 | +# Print an image |
| 77 | +bun run packages/cli/src/index.ts print my-label.png |
| 78 | +``` |
| 79 | + |
| 80 | +## Architecture |
| 81 | + |
| 82 | +``` |
| 83 | +βββββββββββββββββββββββββββββββββββββββ |
| 84 | +β CLI β commander + chalk + ora |
| 85 | +βββββββββββββββββββββββββββββββββββββββ€ |
| 86 | +β Printer orchestrator β connect, print, events |
| 87 | +ββββββββββββ¬βββββββββββ¬ββββββββββββββββ€ |
| 88 | +β Image β Protocol β Device β |
| 89 | +β pipeline β (L11) β registry β |
| 90 | +ββββββββββββ΄βββββββββββ΄ββββββββββββββββ€ |
| 91 | +β FlowController β Credit-based BLE chunking |
| 92 | +βββββββββββββββββββββββββββββββββββββββ€ |
| 93 | +β BleTransport (injected) β Noble, Web Bluetooth, etc. |
| 94 | +βββββββββββββββββββββββββββββββββββββββ |
| 95 | +``` |
| 96 | + |
| 97 | +**Image pipeline:** RGBA β grayscale β Floyd-Steinberg dither β 1-bit pack β raster commands |
| 98 | + |
| 99 | +**Flow control:** Credit-based backpressure prevents buffer overflow on the printer. The host waits for credit grants before sending each packet. |
| 100 | + |
| 101 | +**Protocol:** L11 is a binary raster protocol. The printer has no built-in fonts β all content (text, images, barcodes) is rendered to a bitmap before sending. |
| 102 | + |
| 103 | +## Project Structure |
| 104 | + |
| 105 | +``` |
| 106 | +thermoprint/ |
| 107 | +βββ packages/ |
| 108 | +β βββ core/ |
| 109 | +β β βββ src/ |
| 110 | +β β βββ printer.ts # Printer orchestrator |
| 111 | +β β βββ discovery.ts # BLE discovery helpers |
| 112 | +β β βββ transport/ # BleTransport interface + FlowController |
| 113 | +β β βββ protocol/l11/ # L11 binary protocol |
| 114 | +β β βββ device/ # Device profiles + registry |
| 115 | +β β βββ image/ # RGBA β 1bpp pipeline |
| 116 | +β βββ cli/ |
| 117 | +β βββ src/ |
| 118 | +β βββ cli/commands/ # discover, print, status, config |
| 119 | +β βββ transport/noble.ts # Noble BLE adapter |
| 120 | +β βββ image/load.ts # Image loading with sharp |
| 121 | +β βββ store/config.ts # ~/.thermoprint/config.json |
| 122 | +βββ docs/ # Architecture & guides |
| 123 | +βββ REVERSE_ENGINEERING.md # Protocol documentation |
| 124 | +``` |
| 125 | + |
| 126 | +## Documentation |
| 127 | + |
| 128 | +- [Architecture](docs/architecture.md) β design decisions, layer diagram, data flow |
| 129 | +- [Transport](docs/transport.md) β BleTransport interface and flow control |
| 130 | +- [Image Pipeline](docs/image-pipeline.md) β grayscale, dithering, bit packing |
| 131 | +- [Adding a Printer](docs/adding-a-printer.md) β how to add a new device profile |
| 132 | +- [Reverse Engineering](REVERSE_ENGINEERING.md) β protocol analysis from the Android app |
| 133 | + |
| 134 | +## Tech Stack |
| 135 | + |
| 136 | +- **Runtime:** [Bun](https://bun.sh) |
| 137 | +- **Language:** TypeScript (strict, ESNext) |
| 138 | +- **BLE:** [@stoprocent/noble](https://github.com/nicedoc/noble) (CLI), pluggable via `BleTransport` |
| 139 | +- **Image processing:** [sharp](https://sharp.pixelplumbing.com) |
| 140 | +- **CLI:** [Commander.js](https://github.com/tj/commander.js) + [chalk](https://github.com/chalk/chalk) + [ora](https://github.com/sindresorhus/ora) |
| 141 | + |
| 142 | +## License |
| 143 | + |
| 144 | +MIT |
0 commit comments