scanservjs: put a SANE scanner on the network without installing vendor drivers
SANE scanner nodejs web ui
At a glance
- What is it?
- scanservjs is a web front end for a scanner that speaks SANE, so a machine, a phone or a tablet on the same network can drive a scanner that is physically attached to a Linux host, with no vendor drivers and no vendor software. The image processing is done by ImageMagick and the OCR by Tesseract, and the whole thing runs happily as a container.
- Who is it for?
- scanservjs suits someone with a scanner attached to a Linux box, a NAS or a home server who wants to scan from a phone or a laptop over the network, and who is willing to deal with SANE device permissions.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What it is, and the problem it solves
scanservjs is a web UI frontend for your scanner, and it allows you to share one or more scanners, using SANE, on a network without the need for drivers or complicated installation. The requirements are a SANE scanner, a Linux host or a VM with the necessary USB pass-through, and the software sane-utils, ImageMagick, Tesseract and nodejs. The problem it addresses is visible in the user quotes at the top of the README, which are more useful than a feature list would be. One user found it perfect in a browser and better than the bloated software printer manufacturers ship. Another used it to keep an old HP 3900 scanner working without worrying about drivers and vendor specific interfaces. A third had a Brother scanner whose touchscreen and buttons were broken, meaning the device was useless on its own because a scan could not be triggered, and with this project the scan is triggered remotely. A fourth untethered a scanner from a laptop and noted it will work forever regardless of OS updates since it is all a container.
The feature list, which is mostly imaging pipeline
The features are the imaging pipeline spelled out. Cropping, and source selection between flatbed and ADF. Resolution. Output formats of TIF, JPG, PNG, PDF and TXT with Tesseract OCR, with varying compression settings. Filters for autolevels, threshold and blur. Configurable overrides for all defaults as well as for filters and formats. Multipage scanning with collation for double sided scans. International translations in Arabic, Czech, Dutch, French, German, Hungarian, Italian, Mandarin, Polish, Portuguese in both PT and BR, Russian, Slovak, Spanish, Turkish and Ukrainian, with a help request open for more. Light and dark mode, responsive design, Docker images for amd64, arm64 and armv7, and OpenAPI documentation. The formats list is the part that tells you what the pipeline can produce, since the OCR route is the one that distinguishes a scanner front end from a file drop service.
Three install routes, and the Docker one is the most capable
The install section lists three. On Debian you pipe a bootstrap script into a shell with sudo, passing -v latest. On Arch there is a package, yay -S scanservjs. And on Docker you run the published image detached, publishing port 8080, mounting the dbus socket from the host, restarting unless stopped, naming the container and running it privileged. The privileged flag and the dbus mount are the two details that matter, because SANE talks to the scanner through the session bus, so without /var/run/dbus the container cannot see the device even with the USB device passed through. The Dockerfile in the repository shows the rest of the shape, with a builder stage on node:24-trixie-slim that builds the JavaScript app and a Debian package, and a base stage on debian:trixie-slim that installs nodejs, imagemagick, ipp-usb, sane-airscan, sane-utils and a dozen tesseract language packs including the English, German, Spanish, French, Italian, Dutch, Polish, Portuguese, Russian, Turkish and Simplified Chinese models. The base image is deliberately minimal and reused by the later stages, and the comment says it would all work if that layer did not exist but testing would be slower and more painful.
docker run \
--detach \
--publish 8080:8080 \
--volume /var/run/dbus:/var/run/dbus \
--restart unless-stopped \
--name scanservjs-container \
--privileged sbs20/scanservjs:latestScanner detection is the fragile step, and the documentation says so
The Running scanservjs section is honest about where the difficulty lies. When the app first loads it attempts to detect your scanner, and this step is the most precarious and may either require custom drivers or some additional steps if you are running a network scanner or Docker. The documentation has a dedicated SANE setup page and a troubleshooting page for exactly this. Once the scanner is detected, the pages follow. The Scan page gives access to the controls, and the app will generally find the settings available automatically, although some scanners mis-report their abilities, which is the case where the configuration and device override page comes in. If geometry is available, meaning selecting scan size and position, then cropping is available too. There is batch scanning, with the Auto option if you have a document feeder and Manual if you do not, in which case the app prompts you to change pages between scans.
Output handling, and the file layout the app owns
Any scan operation results in a single file, with the nuance that some formats such as PDF and TIF support multiple pages while others such as PNG and JPG do not, and if the pipeline produces more than one file the app zips them into a single output. Scanned files are saved in a flat directory with a simple web view on the Files page, and the intended usage is to allow the user to save their scans locally, meaning download the files. The app will never delete these files, but the documentation warns that under Docker without volume mapping the files may be lost when you run a new version, which is the one operational trap in the whole design. The README is also clear about what it does not do, stating that users in real life will want to store their scans with their own names, directory structures and cloud services or NAS devices, and that those permutations are beyond the scope of the app. Integration is available instead, through pipeline automation or file actions.
The three part repository, and the older project it grew out of
The Why section is the most interesting paragraph, because it explains a project that exists because the previous one did. This is yet another scanimage web front end, and the question is why. It originally started as an adaptation of phpsane, just to make everything a bit newer, give it a refresh and make it work on minimal installations without ImageMagick, and that earlier version is still available as scanserv but is no longer maintained. The current implementation is different in one significant way, because the current requirements list ImageMagick explicitly. The repository layout shows a three part application, with app-server/ for the backend, app-ui/ for the frontend, and assets/ for static files, plus a build.js that assembles the pieces, a bootstrap.sh for the Debian install path, an entrypoint.sh for the container, a makedeb.sh for packaging, and a docs/ directory. The root package.json orchestrates it, with separate install and build steps for the two sub-projects and a check target that lints, tests, builds and produces the Debian package.
Upkeep, packaging and the API surface
The releases are v3.1.0 on 2026-06-01, v3.2.0 on 2026-07-14 and v3.3.0 on 2026-08-19, and the last push to the repository was on 2026-10-13, with the repository not archived and the copyright held by Sam Strachan for 2016 to 2026. The licence is GPL-2.0. The package version tracks the same numbering, 3.3.0, and the root package.json is marked private because the published artefact is a container image and a Debian package rather than an npm library. There is built-in OpenAPI documentation with an API explorer, reachable at the api-docs path or from the About page, which means the whole surface is available to script against, and the documentation has an Integration page and a Recipes page for that purpose, along with a proxy page and a QNAP page for the NAS case. The repository also carries a SECURITY.md and a CODE_OF_CONDUCT.md, and the CI includes a CodeQL analysis workflow alongside the build workflow.
Editorial conclusion
scanservjs suits someone with a scanner attached to a Linux box, a NAS or a home server who wants to scan from a phone or a laptop over the network, and who is willing to deal with SANE device permissions. It is the wrong choice if you want a desktop application that talks to a scanner plugged into the same machine, since the whole design is about sharing the device rather than using it locally, and a poor fit if you need the scanned files to land somewhere other than the flat directory the app writes to without building an integration for it. Before deploying, read the SANE setup page, because the scanner detection step is the one the documentation calls the most precarious and the most likely to need custom drivers.
Frequently asked questions
What is scanservjs?
It is a web UI frontend for a scanner that speaks SANE, allowing you to share one or more scanners on a network without needing drivers or a complicated installation. It supports any SANE compatible device, and the licence is GPL-2.0.
What do I need to run scanservjs?
A SANE scanner, a Linux host or a VM with the necessary USB pass-through, and the software sane-utils, ImageMagick, Tesseract and nodejs. You can install with the Debian bootstrap script, with an Arch package, or by running the published Docker image.
Why does the scanservjs Docker command mount the dbus socket?
SANE reaches the scanner through the session bus, so the container needs the host's /var/run/dbus mounted to see the device at all. The documented command publishes port 8080, mounts that socket, runs with --privileged, and restarts unless stopped.
What can scanservjs produce from a scan?
Output formats of TIF, JPG, PNG, PDF and TXT with Tesseract OCR, with varying compression settings, and filters for autolevels, threshold and blur. PDF and TIF support multiple pages while PNG and JPG do not, and if the pipeline produces several files they are zipped into one output.
Can I script scanservjs?
Yes, there is built-in OpenAPI documentation with an API explorer, reachable at /api-docs or from the About page. The documentation also covers integration through pipeline automation or file actions, and there are pages for configuration, recipes and using a proxy.
Official sources
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.
[](https://hysenlabs.com/projects/sbs20-scanservjs)Was this useful?