SK58 Printer
Flutter library for SK58 thermal printer via Bluetooth.
Features
- π Bluetooth device scanning with permission handling
- π Connect/disconnect to SK58 thermal printer
- π Print text with styles (bold, underline, sizes) and alignment
- π Print barcodes (Code128, EAN-13, UPC-A, Code39)
- π± Print QR codes
- πΌοΈ Print images with Floyd-Steinberg dithering
- π·οΈ Generic label templates (Sk58Label, Sk58TwoColumnLabel)
- π§ Fluent builder pattern for complex prints
- β Support for Android and Linux
Screenshots
App Interface
| Main Screen | Barcode Demo | Labels Demo |
|---|---|---|
![]() |
![]() |
![]() |
Print Examples
| Barcode Print | QR Code | Label |
|---|---|---|
![]() |
![]() |
![]() |
Receipt Demo (Builder Pattern)

Installation
Add to your pubspec.yaml:
dependencies:
sk58_printer: ^0.2.0
Then run:
flutter pub get
From Git (development version)
If you want to use the latest development version from GitHub:
dependencies:
sk58_printer:
git:
url: https://github.com/mosulache/sk58_printer.git
ref: main
Quick Start
import 'package:sk58_printer/sk58_printer.dart';
// Create scanner and scan for devices
final scanner = Sk58Scanner();
await scanner.startScan();
// Listen for discovered devices
scanner.deviceStream.listen((device) {
print('Found: ${device.name}');
});
// Connect to a device
final printer = await Sk58Printer.connect(device);
// Print text
await printer.printText('Hello World!');
await printer.printText('Centered', align: Sk58Align.center);
// Print QR code
await printer.printQrCode('https://example.com');
// Feed paper and disconnect
await printer.feedLines(3);
await printer.disconnect();
Advanced Usage
Print Barcodes
// Code 128 (alphanumeric)
await printer.printBarcode('ABC-12345', type: BarcodeType.code128);
// EAN-13 (13 digits)
await printer.printBarcode('5901234123457', type: BarcodeType.ean13);
// UPC-A (12 digits)
await printer.printBarcode('012345678905', type: BarcodeType.upcA);
// Code 39
await printer.printBarcode('CODE39', type: BarcodeType.code39);
Print Images
final imageBytes = await File('logo.png').readAsBytes();
// Print with dithering (better for photos/grayscale)
await printer.printImage(imageBytes, dithering: true);
// Print with threshold (better for logos/line art)
await printer.printImage(imageBytes, dithering: false, threshold: 128);
// Resize to specific width
await printer.printImage(imageBytes, maxWidth: 200);
// For mobile printers or small labels, use bandMode for reliable printing
await printer.printImage(imageBytes, maxWidth: 280, bandMode: true);
Note: Use
bandMode: truefor mobile thermal printers or when printing on small labels (e.g., 40x15mm). This sends the image in smaller chunks using ESC * 33 (24-dot double density) which is more reliable for printers with limited buffers.
Use Templates
// Simple label
await printer.printTemplate(
Sk58Label(
title: 'TORX 4x50',
subtitle: 'Cap T20 - Inox A2',
qrData: 'SKU-12345',
),
);
// Two-column label
await printer.printTemplate(
Sk58TwoColumnLabel(
title: 'Product Info',
rows: [
('Type', 'TORX'),
('Size', '4x50mm'),
('Head', 'T20'),
],
),
);
Builder Pattern (for complex prints)
await printer.build()
.header('DEMO STORE')
.text('123 Main Street', align: Sk58Align.center)
.doubleLine()
.text('RECEIPT', style: Sk58TextStyle.boldStyle, align: Sk58Align.center)
.line()
.row('Coffee', '\$3.50')
.row('Sandwich', '\$8.00')
.line()
.row('TOTAL', '\$11.50')
.feed(1)
.qrCode('https://receipt.example.com/12345')
.feed(3)
.execute();
Text Styles
// Bold text
await printer.printText('Bold', style: Sk58TextStyle.boldStyle);
// Large text
await printer.printText('Large', style: const Sk58TextStyle(size: Sk58FontSize.large));
// Combined styles
await printer.printText(
'Bold + Underline',
style: const Sk58TextStyle(bold: true, underline: true),
);
// Available sizes: normal, wide, tall, large
Printer Specifications (SK58)
Print Area
| Specification | Value |
|---|---|
| Paper width | 58mm |
| Effective print width | 48mm (384 dots) |
| Resolution | 203 DPI (8 dots/mm) |
| Max characters per line | 32 (normal font) |
Label Printing - Dead Zone
β οΈ Important: When printing on label paper, the printer has a non-printable "dead zone" at the top of each label where the print head cannot reach.
| Label Type | Dead Zone | Notes |
|---|---|---|
| Gap labels | ~4mm (32 dots) | Empirically measured |
| Black mark labels | ~3-5mm | Varies by printer |
Example for 40x15mm label:
- Total label height: 15mm (120 dots)
- Dead zone: ~4mm (32 dots)
- Actual printable height: ~11mm (88 dots)
Image sizing recommendation:
For 40x15mm label β Image should be max 320 x 88 pixels
For 50x25mm label β Image should be max 384 x 168 pixels
For 50x30mm label β Image should be max 384 x 208 pixels
The example app includes a realistic label preview that shows:
- The dead zone (grey area marked "NO PRINT")
- The actual printable area (white)
- How your image fits on the label
Label Commands
// Print image on label (no extra feed after image)
await printer.printImage(imageBytes, bandMode: true, feedAfter: false);
// Eject to next label (GS FF command)
await printer.printAndPeel();
// Or use form feed
await printer.formFeed();
Platform Setup
Android
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Linux
Ensure BlueZ is installed and your user has bluetooth permissions:
sudo apt install bluez
sudo usermod -a -G bluetooth $USER
!! linux support requires more testing / documentation
Example App
The example/ folder contains a complete demo app with:
- Text printing with styles
- Barcode printing (all types)
- Image printing with dithering options
- Simple Label templates
- Builder pattern demos
Run it:
cd example
flutter run
API Reference
Sk58Printer
| Method | Description |
|---|---|
connect(device) |
Connect to a BLE device |
disconnect() |
Disconnect from printer |
printText(text, {style, align}) |
Print text |
printQrCode(data, {size}) |
Print QR code |
printBarcode(data, {type, height, width}) |
Print barcode |
printImage(bytes, {maxWidth, dithering, bandMode}) |
Print image |
printTemplate(template) |
Print a template |
build() |
Get a print builder |
feedLines(n) |
Feed n lines |
printLine({char}) |
Print horizontal line |
Sk58Scanner
| Method | Description |
|---|---|
startScan() |
Start scanning for devices |
stopScan() |
Stop scanning |
deviceStream |
Stream of discovered devices |
Third-Party Licenses
This project uses the following open-source libraries:
- universal_ble - BSD-3-Clause License (license)
- permission_handler - MIT License (license)
- image - MIT License (license)
- flutter_lints - BSD-3-Clause License (license)
License
MIT License
Libraries
- sk58_printer
- SK58 Thermal Printer Library





