A CUPS driver for Niimbot thermal label printers on Linux. Wraps the niimprint Python library as a CUPS filter, enabling printing from any application — including Windows clients via IPP over the network.
Tested on Raspberry Pi 4B running Raspberry Pi OS Bookworm (64-bit) with a Niimbot B21
(newer firmware, VID 3513:0002, CDC-ACM interface). Should work on any Debian/Ubuntu-based system.
| Model | Max width | DPI | niimprint name | USB chip | Status |
|---|---|---|---|---|---|
| B21 | 50 mm | 203 | b21 |
CDC-ACM (3513) or CP210x (10c4) | ✓ Tested |
| B21 Pro | 50 mm | 300 | b21 |
CP210x | ✓ Supported |
| B1 | 50 mm | 203 | b1 |
CP210x | ✓ Supported |
| B18 | 50 mm | 203 | b18 |
CP210x | ✓ Supported |
| D11 | 15 mm | 203 | d11 |
CH340 | ✓ Supported |
| D110 | 15 mm | 203 | d110 |
CH340 | ✓ Supported |
| D21 | 15 mm | 203 | d11* |
CH340 | ✓ Supported |
| M2 | 50 mm | 300 | b21† |
unknown | ⚠ Experimental |
| M3 | 78 mm | 300 | b21† |
unknown | ⚠ Experimental |
* D21 uses the d11 niimprint model — protocol is identical.
† M2/M3 are not yet natively supported by niimprint; mapped to b21 as the closest alias.
App / Windows client
│ PDF via IPP
▼
CUPS
│ application/pdf
▼
niimbot filter ←─── DEVICE_URI env var (device path)
│ PNG @ 203/300 dpi
▼
niimprint CLI
│ Niimbot serial protocol
▼
/dev/ttyACM0 (or ttyUSB0)
│ USB
▼
Printer
CUPS receives a PDF job, the niimbot filter converts it to a monochrome PNG
at the correct DPI using pdftoppm, then calls niimprint to send it to the
printer over USB (or Bluetooth).
A custom niimbot-null backend is used instead of the standard serial:// or
usb:// backends. This prevents the CUPS backend from competing with niimprint
for the serial port, which would cause print failures.
# System packages
sudo apt install cups python3 python3-pip poppler-utils
# niimprint Python package
pip3 install niimprint --break-system-packagesgit clone https://github.com/HardwareHarry/niimbot-cups.git
cd niimbot-cups
sudo bash install/install.shThe installer:
- Installs the CUPS filter, null backend, and PPD
- Installs udev rules for USB device permissions
- Patches niimprint for CDC-ACM firmware compatibility (newer B21)
- Reloads CUPS and udev
Plug in the printer, then:
ls -la /dev/niimbot* /dev/ttyACM* /dev/ttyUSB* 2>/dev/nullThe udev rules create stable symlinks:
/dev/niimbot_b21→ newer B21 firmware (CDC-ACM, VID 3513)/dev/niimbot_b21_cp210x→ older B21 firmware (CP210x)/dev/niimbot_d11→ D11 / D110 / D21
Use lsusb and dmesg | tail -30 to identify which applies to your device.
sudo lpadmin -p NiimbotB21 -E \
-v 'niimbot-null:/dev/niimbot_b21' \
-P /usr/share/cups/model/niimbot.ppd \
-o NiimbotModel=b21 \
-o NiimbotDensity=3 \
-o PageSize=Niimbot_50x30mm \
-o printer-error-policy=retry-jobsudo lpadmin -p NiimbotB21 -E \
-v 'niimbot-null:/dev/niimbot_b21_cp210x' \
-P /usr/share/cups/model/niimbot.ppd \
-o NiimbotModel=b21 \
-o NiimbotDensity=3 \
-o PageSize=Niimbot_50x30mm \
-o printer-error-policy=retry-jobsudo lpadmin -p NiimbotD11 -E \
-v 'niimbot-null:/dev/niimbot_d11' \
-P /usr/share/cups/model/niimbot.ppd \
-o NiimbotModel=d11 \
-o NiimbotDensity=3 \
-o PageSize=Niimbot_D11_14x25mm \
-o printer-error-policy=retry-jobThe NiimbotModel, NiimbotDensity etc. PPD options are visible in print
dialogs but are not reliably passed to the filter by all CUPS versions.
Always set them at registration time using lpadmin -o as shown above.
With printer-error-policy=retry-job, if the printer is in power-saving mode
when a job arrives, CUPS holds the job and retries every ~30 seconds. The job
prints automatically when the printer is powered on — no intervention needed.
# Edit /etc/cups/cupsd.conf:
# Change: Listen localhost:631
# To: Port 631
# Add: ServerAlias *
# Add Allow from your subnet to <Location /> and <Location /admin>
sudo cupsctl --share-printers
sudo systemctl restart cupsWindows clients can then add the printer at:
http://<pi-hostname-or-ip>:631/printers/NiimbotB21
Use the Generic → MS Publisher Imagesetter driver on Windows when prompted.
# Pair first with bluetoothctl, then:
sudo lpadmin -p NiimbotB21_BT -E \
-v 'niimbot-null:bluetooth' \
-P /usr/share/cups/model/niimbot.ppd \
-o NiimbotModel=b21 \
-o NiimbotConn=bluetooth \
-o NiimbotAddr=AA:BB:CC:DD:EE:FF \
-o printer-error-policy=retry-jobsudo tail -f /var/log/cups/error_log
# Enable debug logging with:
sudo cupsctl --debug-loggingsudo -u lp env DEVICE_URI='niimbot-null:/dev/niimbot_b21' \
/usr/lib/cups/filter/niimbot 1 user "Test" 1 \
"NiimbotModel=b21 NiimbotDensity=3 PageSize=Niimbot_50x30mm" \
/path/to/test.pdf# Check udev symlink exists
ls -la /dev/niimbot_b21
# If not, check VID:PID and reload rules
lsusb | grep -i niimbot
sudo udevadm control --reload-rules && sudo udevadm triggerThe B21 with newer firmware sometimes doesn't respond to the set_label_density
command. The installer patches niimprint to handle this gracefully. If you
installed niimprint manually after running the installer, re-run the installer
or apply the patch manually:
PRINTER_PY=$(find /usr/local/lib -name "printer.py" -path "*/niimprint/*" | head -1)
sudo python3 -c "
src = open('$PRINTER_PY').read()
src = src.replace(
'return bool(packet.data[0])',
'return bool(packet.data[0]) if packet is not None else True'
)
open('$PRINTER_PY', 'w').write(src)
print('Patched')
"The windows/ directory contains:
Install-NiimbotForms.ps1— PowerShell script to install custom paper sizesniimbot-forms.reg— Registry file with the same paper sizes
Run as Administrator on Windows to add Niimbot label sizes to the system paper size list, making them available in all Windows applications.
niimbot-cups/
├── filter/
│ └── niimbot ← CUPS filter (Python 3, executable)
├── ppd/
│ └── niimbot.ppd ← PPD (label sizes, model options)
├── install/
│ ├── install.sh ← Installer script
│ ├── niimbot-null ← Null CUPS backend (bash, executable)
│ └── 60-niimbot.rules ← udev rules for USB device permissions
├── windows/
│ ├── Install-NiimbotForms.ps1 ← Windows paper size installer
│ └── niimbot-forms.reg ← Windows registry paper sizes
└── README.md
MIT — same as niimprint upstream.