Open-source project
MultiMote/niimblue avatar
MultiMote/niimblue

niimblue designs and prints NIIMBOT labels from a browser tab, with no data leaving the page

🖨 NIIMBOT custom web client/app. Design and print labels with NIIMBOT printers directly from your PC or mobile web browser!

799 stars127 forksTypeScriptMIT

At a glance

What is it?
niimblue is a TypeScript and Svelte web client for NIIMBOT thermal label printers that talks Bluetooth or USB directly from the browser, keeps label data on the client, and can also ship as a Capacitor Android app and a Tauri Windows app. It leans on a separate protocol library, NiimBlueLib, that reverse engineered the printer protocol.
Who is it for?
niimblue fits someone with a NIIMBOT printer who wants a label editor in a browser tab, works offline, and does not want to sign up for a vendor account or send label data to a server. It does not fit a browser without Web Bluetooth or Web Serial, and it does not fit a team that needs a guaranteed model list, since the README states there is no exact list of supported models and asks users to contribute to one.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A label printer driven from a browser tab

niimblue is a custom web client for NIIMBOT printers, and the pitch in one line is that you can design and print labels right from your browser.

The supported printer families are in the topic tags: niimbot, niimbot-b1, niimbot-b21 and niimbot-d110, along with thermal-printer and label-printer. The README is careful about the scope of that support. There is no exact list of supported models in this project, and the stated aim is to support the maximum number of models. A list of tested models lives in an issue on the companion library, and the README asks owners of other models to comment there.

The application is a Svelte and TypeScript project built with Vite, and the homepage is niim.blue with a dev and a second production deployment listed alongside it.

The line that defines the product is the first feature: privacy first. The application works completely offline on the browser side and does not send any data, except for downloading application files and importing ZPL labels, and label data is stored in your browser.

That is an unusual position for a printing service and it is worth understanding why it is possible. The printer is reached over a local radio or cable, not over the network, so there is no server in the middle. That is also why the project exists at all: the vendor's own application is a closed client, and this one is an open one that works with the hardware directly.

The protocol work lives in a separate library

The README credits NiimBlueLib as being used for communication, and the package.json names the dependency as @mmote/niimbluelib at version 0.47.0.

So the split is: this repository is the user interface, the editor, the standalone apps and the deployment, and the reverse engineering of the printer protocol is a separate project. That is a sensible separation, and it has a consequence for anyone evaluating the whole thing. The set of printers that work is a property of the library, not of the web client.

The topic tags confirm the nature of the work: reverse-engineering sits alongside the printer families, and the README describes itself as the most complete implementation of the NIIMBOT protocol, with a link to the protocol documentation on the community wiki.

The protocol reference also explains the packet dump workflow. If your printer model does not print, the README asks you to make a packet dump of a print made with the official application. That is the contribution loop: capture what the vendor client sends, work out what the bytes mean, and teach the library.

It is worth naming what this means for trust. The printer protocol here was worked out by observing the vendor's own client rather than from a published specification, which is normal for consumer hardware and means the library needs to be maintained as the vendor's firmware evolves.

What the browser can and cannot do about the printer

There are two transports, and each has a browser requirement.

For Bluetooth, your browser must support the Web Bluetooth API, with the README linking the compatibility table. For serial communication, the browser must support the Web Serial API, with its own compatibility table. The summary is that modern Chrome-based browsers should usually work, and in some systems you need to enable Chrome Web Bluetooth or Experimental Web Platform Features through the chrome://flags page.

Safari is the awkward case and the README handles it explicitly. Safari has no native Web Bluetooth, so a third party extension called beacio enables Web Bluetooth under Safari, with setup details on that project's own site.

So the honest summary of the requirements is that this is a Chrome-family tool with a documented workaround for Safari, and a hard requirement on a browser with Web Bluetooth or Web Serial.

There is a second route around that requirement, and it is the standalone apps. The README lists an Android app based on Capacitor and a Windows app based on Tauri that uses Edge as its web backend. The dependencies confirm both: @capacitor/core, @capacitor/filesystem and @capacitor/share in the main dependency list, and a standalone-apps directory in the repository root. The Capacitor filesystem and share plugins are there for saving and sharing labels from the Android build.

The topic tags list web, webui, web-bluetooth, capacitor, android and custom-app, which is the same set of decisions restated.

The editor, the preview and the post-processing

The feature list is short, and the interesting part is what the print preview does.

The rich label editor covers label saving and import and export. The print preview lets you see how your label will look after post-processing, and several post-processing algorithms are available. The screenshots in the README show the label properties dialog, the save and load menu, the print preview dialog, the dithering screen, the templating screen and the dynamic data or batch screen.

Dithering matters more than it sounds. Thermal printers have a very limited palette, and a design that looks fine on screen can turn into a mud of grey on a 203 dpi print head. A preview that shows the dithered result lets you pick a different algorithm before you waste a label, and the README notes that images may be outdated in the screenshot section rather than showing a workflow.

Templating and dynamic data cover the batch case. Templating is for a label that repeats with different values in it, and the dynamic data or batch screen is for producing many labels from a table, which is how you print shipping labels in quantity rather than one at a time.

There is also a troubleshooting note that is more useful than it sounds: if you have printing problems, try different print task versions in the print preview dialog, and make one the default by pressing the Lock button. Different printer models evidently expect different task formats, and the preview dialog is where you pick between them.

The label formats are handled too. ZPL labels can be imported, and pdfjs-dist, qrcode-generator, fabric and d3-dsv in the dependency list cover PDF viewing, QR generation, canvas drawing and delimited data respectively.

Building it yourself, and what the Docker image actually serves

The development section is a numbered list: install git, install nodejs, clone the repository, install dependencies, run the dev server.

bash
git clone https://github.com/MultiMote/niimblue.git
bash
npm i

Then there are two ways to run it.

bash
npm run dev-check
bash
npm run dev

The first checks the code and then runs, and the second just runs. The check is svelte-check against the tsconfig, so dev-check is the type check plus the dev server in one command.

For deployment, the README gives two options and one warning: HTTPS is required for non-localhost deployments. Serving static files means running npm run build, which results in a build to dist, or downloading niimblue-dist.zip from the releases. A Docker image is also available, with the instructions in the wiki.

The Dockerfile is a two-stage build that ends in nginx.

dockerfile
FROM node:25-alpine AS builder

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm ci

COPY . .

RUN npm run sv-check && npm run build

FROM nginx:1.27-alpine AS server

COPY --from=builder /app/dist/ /usr/share/nginx/html/

EXPOSE 80

The type check runs as part of the image build, so a broken type in a pull request fails the Docker build rather than the container at runtime.

There is one detail in the deployment section that is easy to miss. The HTTPS requirement is not about the site being a web app. It is because Web Bluetooth and Web Serial are restricted to secure contexts, so a self-hosted instance on a plain HTTP address cannot reach the printer at all, regardless of how the frontend is built.

Where niimblue is the wrong choice

The first limitation is the browser dependency, and it is a hard one for an organisation with a managed browser estate. Web Bluetooth and Web Serial are still not baseline across browsers, Safari needs a third party extension, and Chrome flags may be required. If your users are on managed Edge or on a locked down browser profile, the standalone apps are the route, and that is a different distribution problem.

The second is the absence of a supported model list. The README is upfront that there is no exact list, and asks users to comment on the tested models issue for models they own. A production deployment that has to guarantee a specific printer works is relying on a community list.

The third is the firmware dependency. The topic tags include firmware-update, and the supported printers include the D110, which is a printer with a screen. What that implies for the protocol is a maintenance commitment rather than a feature, because the bytes the printer expects can change with its own firmware.

The fourth is that the client stores label data in your browser. That is the privacy property and it is also the failure mode: clearing site data, or opening the editor in a private window, loses the saved labels unless they were exported. The README's save and export feature is the mitigation, and it means the workflow needs an export step.

The fifth is scope. This prints labels on NIIMBOT hardware. It is not a general print service and it is not a barcode label system for enterprise use, and it offers no multi-user, no scheduling and no inventory.

How it compares with the vendor application

The alternative is the official NIIMBOT application, which is what the protocol was reverse engineered from and what the README tells you to use when making a packet dump.

The vendor client has the advantages you would expect. It is supported, it is tested against the hardware by the people who make it, and it works with the full range of models without anyone maintaining a community list. It also has the disadvantages you would expect from a closed client on an app store: an account, a server, and label data leaving your machine.

niimblue inverts that. The browser holds your label data and the print happens locally over the radio or the cable. The label editor is richer than a vendor app tends to be, with templating, batch dynamic data and a dithered print preview. And it is open source under MIT, so the protocol work is public and the community wiki at printers.niim.blue documents it.

The cost is the model support, which is the reverse: the vendor client knows what it supports, and this one discovers it.

There is a third route worth naming for anyone running this in a shop or a warehouse: the Docker image. You can host your own instance, keep it on your own network and give people a URL that reaches your printers over the network rather than over Bluetooth, which removes the browser requirement for the printing step while keeping the label data on your own infrastructure.

The honest summary is that niimblue wins on privacy, on editor features and on openness, and loses on guaranteed model support and on the fact that it is one person's project, maintained alongside a protocol library.

Editorial conclusion

niimblue fits someone with a NIIMBOT printer who wants a label editor in a browser tab, works offline, and does not want to sign up for a vendor account or send label data to a server. It does not fit a browser without Web Bluetooth or Web Serial, and it does not fit a team that needs a guaranteed model list, since the README states there is no exact list of supported models and asks users to contribute to one. Before adopting, check that your browser exposes Web Bluetooth, confirm your exact printer model appears in the tested models list, and read the print preview dialog's task version options, because the README's own troubleshooting advice is to try a different print task version when a model does not print.

Frequently asked questions

What is niimblue and which printers does it support?

It is a custom web client for NIIMBOT thermal label printers, letting you design and print labels from a browser over Bluetooth or USB. The README states there is no exact list of supported models in this project, that the aim is to support as many as possible, and that a list of tested models is kept in an issue on the companion library.

Does niimblue send my label data to a server?

No. The README states the application works completely offline on the browser side and does not send any data, except for downloading application files and importing ZPL labels, and that label data is stored in your browser.

What browser does niimblue need?

It needs Web Bluetooth for Bluetooth printers and Web Serial for serial connections, both of which have browser compatibility tables linked in the README. Modern Chrome-based browsers should usually work, some systems need Chrome Web Bluetooth or Experimental Web Platform Features enabled, and Safari needs the beacio extension.

How do I run the niimblue development server?

Install git and nodejs, clone the repository with git clone https://github.com/MultiMote/niimblue.git, install dependencies with npm i, then run npm run dev-check to type check and start the server, or npm run dev to just start it. The build script is npm run build, which outputs to dist.

My printer model does not print with niimblue, what should I do?

The README advises trying different print task versions in the print preview dialog and locking one as the default with the Lock button. If the model still does not work, it asks you to make a packet dump of a print made with the official application so the protocol can be extended.

Official sources

  1. License: MIT
  2. MultiMote/niimblue on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/multimote-niimblue.svg)](https://hysenlabs.com/projects/multimote-niimblue)

Was this useful?