@bobfrankston/brother-label
v1.1.11
Published
API and CLI for printing labels on Brother P-touch printers
Maintainers
Readme
@bobfrankston/brother-label
Print labels to Brother P-touch label printers from Node.js. Supports text, HTML, images, and QR codes.
Installation
npm install -g @bobfrankston/brother-labelCommand Line Usage
Print text
brother-print print "Hello World"
brother-print print "Line 1\\nLine 2" # Multi-linePrint QR code
brother-print qr "https://example.com"
brother-print qr "https://example.com" -l "My Site" # With text label
brother-print qr "any data" -o qr.png # Save to filePrint HTML
brother-print html label.htmlInline QR codes in HTML
Use <img qr="data"> to embed QR codes directly in HTML - they're converted to base64 at render time:
<img qr="https://example.com" style="width:10mm; height:10mm">
<img qr="any data here" class="my-qr">Multi-segment labels
Combine multiple -text and -qr segments on a single label, printed side-by-side in order:
brother-print -text "Hello" -qr "https://example.com"
brother-print -text "Top\nBottom" -qr "https://example.com" -text "More text"
brother-print -t "Label" -q "data" -o combined.pngPrint image
brother-print image photo.pngPreview (save without printing)
brother-print preview "Test Label" -o preview.pngConfiguration
brother-print config --show # Show current config
brother-print config -s 12 # Set default tape size
brother-print config -p "Brother PT-P710BT" # Set default printer
brother-print list # List Brother printersPrint clipboard contents
brother-print -clip # auto-detect: image if present, else textOptions
| Option | Description |
|--------|-------------|
| -t, --text | Force input as literal text; repeatable for multi-segment labels |
| -qr <data> | QR code segment; repeatable for multi-segment labels |
| -tape <size> | Tape size: 6, 9, 12, 18, 24 (mm); auto-detected if omitted |
| -p, --printer <name> | Printer name |
| -o, --output <file> | Save to file instead of printing |
| -a, --aspect <ratio> | Aspect ratio width:height for HTML (e.g., 3.5:2) |
| -ht, --height <size> | Text height: 12mm, .5in, or 50% (of tape height) |
| -s, --space <size> | Space between segments: 12px, 1mm, .2in |
| -w, --html | Force input as HTML file path |
| -i, --image | Force input as image file path |
| -c, --clip | Read content from clipboard (image preferred, then text) |
| -no-wait | Fail immediately if printer is offline (default: wait) |
| -timeout <secs> | Max wait time when printer is offline |
| -interval <secs> | Polling interval while waiting (default: 2) |
| -ql <host> | Print to a Brother QL series printer over TCP/9100 (e.g. -ql ql720 or -ql 1.2.3.4); auto-set when -p resolves to a QL-* queue |
| -ql-media <id> | QL media firmware id (271 = DK-11201 29×90mm, 259 = DK-22205 62mm continuous); only needed when status detection and the Windows driver both fail |
| -vb, -verbose | Print extra QL diagnostic messages (status outcome, media source) |
| -mdns | With list: also discover network printers via mDNS |
Single-hyphen long options are supported: -text works the same as --text, -tape as --tape, etc. Single letters are strict: -t means --text, not the start of -tape.
Offline handling
By default print() waits for the printer to come online if it's asleep. Use -no-wait to fail immediately, or -timeout <secs> to bound the wait. Use brother-print status to check the current online state. The wait reports any other Brother printers that are online as alternatives.
QL series printers (DK die-cut / continuous labels)
QL printers (e.g. QL-720NW, QL-820NWB) print over raw TCP/9100, not via the Windows XPS driver. When -p resolves to a QL-* queue, brother-label auto-routes through the QL path and pulls the host from the printer port; you can also use -ql <host> directly to skip the queue lookup.
Media is auto-detected in this priority order:
- Printer status response (newer QL models reply over TCP)
- Windows print driver's cached media (DefaultPrintTicket XML)
-ql-media <id>override
If the bare hostname stored in the printer port doesn't resolve via DNS (common with Brother's BRWxxxx names), brother-label tries OS DNS suffixes, .local mDNS, then a direct multicast mDNS query.
brother-print -p ql720 "Hello" # auto-routes to QL TCP path
brother-print -ql 172.20.1.127 "Hello" # explicit host
brother-print -ql ql720 -ql-media 271 "Hello" # force DK-11201
brother-print -p ql720 -vb "Hello" # verbose: show status / media sourceAPI Usage
Print text
import { print } from "@bobfrankston/brother-label";
await print({ text: "Hello World" });
await print({ text: "Hello", tape: 12 }); // 12mm tapePrint QR code
import { print, render } from "@bobfrankston/brother-label";
// Print QR code
await print({ qr: "https://example.com" });
// QR code with text label
await print({ qr: "https://example.com", qrLabel: "My Site" });
// Render to buffer without printing
const buffer = await render({ qr: "https://example.com" });Print HTML
// From file
await print({ htmlPath: "label.html" });
// Inline HTML
await print({
html: "<div style='font-size:24px'>Hello</div>",
basePath: __dirname // For resolving relative resources
});
// With aspect ratio
await print({ htmlPath: "label.html", aspect: "4:1" });
// HTML with inline QR codes - <img qr="..."> auto-converted to base64
await print({
html: `<img qr="https://example.com" style="width:10mm">`,
});Print image
// From file
await print({ imagePath: "photo.png" });
// From buffer
await print({ imageBuffer: fs.readFileSync("photo.png") });Print clipboard contents
await print({ clip: true }); // image if present, else textOffline handling
await print({
text: "Hello",
onWaiting: (status, elapsedMs, alternatives) => {
console.log(`waiting on ${status.name} (${Math.floor(elapsedMs/1000)}s)`);
},
waitTimeoutMs: 60_000,
});
await print({ text: "Hello", wait: false }); // fail immediately if offlineCross-driver code
import type { LabelPrinter } from "@bobfrankston/label-core";
import { brotherPrinter } from "@bobfrankston/brother-label";
import { dymoPrinter } from "@bobfrankston/dymo-print";
async function printOn(p: LabelPrinter, text: string) {
await p.print({ text });
}Configuration
import { getConfig, setConfig, listPrinters } from "@bobfrankston/brother-label";
// Get current config
const config = getConfig();
console.log(config.defaultTape); // 12
console.log(config.defaultPrinter); // "Brother PT-P710BT"
// Set defaults
setConfig({ defaultTape: 24, defaultPrinter: "Brother PT-P710BT" });
// List printers
const printers = await listPrinters();
printers.forEach(p => console.log(p.name));Render without printing
import { render } from "@bobfrankston/brother-label";
const buffer = await render({ text: "Hello" });
fs.writeFileSync("label.png", buffer);API Reference
Types
type TapeSize = 6 | 9 | 12 | 18 | 24;
interface PrintOptions {
// Content (exactly one required)
text?: string; // Plain text
html?: string; // Inline HTML
htmlPath?: string; // Path to HTML file
textFile?: string; // Path to text file
imagePath?: string; // Path to image file
imageBuffer?: Buffer; // Image buffer
qr?: string; // QR code data
// Settings
tape?: TapeSize; // Tape size in mm
printer?: string; // Printer name
basePath?: string; // Base path for HTML resources
aspect?: string; // Aspect ratio for HTML (e.g., "4:1")
qrLabel?: string; // Text label beside QR code
}
interface PrintResult {
image: Buffer; // The rendered image
}Functions
| Function | Description |
|----------|-------------|
| print(options) | Render and print a label |
| render(options) | Render label to PNG buffer |
| renderSegments(segments, tape?, textHeight?) | Render multiple text/qr segments side-by-side |
| printSegments(segments, options?) | Render and print multiple segments |
| getConfig() | Get current configuration |
| setConfig(config) | Set default tape/printer |
| getConfigPath() | Get config file path |
| listPrinters() | List Brother printers |
Supported Printers
- Brother PT-P710BT (tested)
- Other Brother P-touch printers (should work)
- Brother QL-720NW (tested via TCP/9100; status detection unsupported by firmware, falls back to Windows-driver media)
- Brother QL-820NWB (tested via TCP/9100)
- Other QL series (should work — protocol is shared)
Requirements
- Windows (uses Windows printing APIs)
- Node.js 20+
- Puppeteer (for HTML rendering)
