thermaltool is a CLI for probing and printing to CSN-A2-style serial
thermal printers. It supports text styling, Markdown receipts, images, QR codes,
barcodes, heat/density configuration, status probes, and raw ESC/POS bytes.
From this checkout:
go install ./cmd/thermaltool
Make sure your Go bin directory is on PATH:
export PATH="$(go env GOPATH)/bin:$PATH"
Create a .env file in the directory where you run thermaltool:
THERMALTOOL_PORT=/dev/cu.usbserial-A50285BI THERMALTOOL_BAUD=9600
thermaltool loads .env automatically. Aliases are also accepted:
THERMALTOOL_BAUD_RATE=9600 THERMAL_PRINTER_PORT=/dev/cu.usbserial-A50285BI THERMAL_PRINTER_BAUD=9600
Flags override .env, so you can still run one-off commands like:
thermaltool status --port /dev/cu.usbserial-A50285BI --baud 19200
For live transcription, also provide an OpenAI API token:
OPENAI_API_KEY=sk-...
OPENAI_API_TOKEN is accepted as an alias, or use
thermaltool live-transcribe --api-key-env NAME for a custom environment
variable.
List serial ports:
thermaltool ports
Probe status and baud:
thermaltool status thermaltool scan-baud --bauds 9600,19200
Print text:
thermaltool print-text "Hello from thermaltool" thermaltool print-text --bold --double-width --underline thick "SALE" thermaltool print-text --wrap --columns 32 "Long receipt text that should wrap."
print-text style flags are scoped to that print and restored afterward. Use
configure for persistent printer mode changes.
Print Markdown:
thermaltool print-markdown --file receipt.md
thermaltool print-markdown "# Order 123\n\n- Paid\n- Packed"
thermaltool print-markdown --file receipt.md --image-dither --image-width 256Markdown images such as  are loaded from local paths,
converted to printer bitmap data, and printed inline. Relative image paths use
the Markdown file directory, or --image-base-dir for stdin/direct input.
Remote image URLs are not fetched.
Embed QR codes and barcodes in Markdown:
```thermal qr data: https://example.com/order/123 size: 192 ecc: medium ``` ```thermal barcode code128 data: ABC123 hri: below height: 96 module-width: 3 ```
Print QR codes and barcodes directly:
thermaltool print-qr "https://example.com" thermaltool print-barcode --type code128 --hri below "ABC123" thermaltool print-barcode --type datamatrix --size 160 "ABC123"
Print an image:
thermaltool print-image --dither image.png thermaltool print-image --threshold 180 image.png
Bitmap output from print-image, print-qr, print-barcode,
print-nv-bitmap, bitmap-probe, Markdown images, and Markdown QR/barcode
blocks now sends --heat-dots 255 --heat-time 255 --heat-interval 1 by default
for darker, sharper graphics. Use --dark to add maximum print density on top.
Advanced tuning is available with --density, --break-time, --heat-dots,
--heat-time, and --heat-interval; graphics commands restore factory heat
after the bitmap so later text does not inherit the aggressive profile. Use
configure for persistent printer settings.
Configure printer behavior:
thermaltool configure --heat-dots 11 --heat-time 120 --heat-interval 40 thermaltool configure --density 10 --break-time 2
Send raw bytes:
thermaltool raw "1b 40"Live transcribe from the Mac microphone and print finalized lines to the thermal printer:
thermaltool live-transcribe --language en thermaltool live-transcribe --no-echo
The command streams 24 kHz mono PCM from the default microphone to OpenAI's
realtime transcription API, commits a line after local speech silence, prints
the finalized transcript to the printer, and echoes the same line to stdout
unless --no-echo is set. On macOS, the terminal app running thermaltool may
need microphone permission.
The WebSocket connection requests transcription mode directly. --model
configures audio.input.transcription.model and defaults to
gpt-realtime-whisper.
Run command help for the full flag set:
thermaltool --help thermaltool print-markdown --help thermaltool print-barcode --help