docuvault-scanner
v1.0.3
Published
Single-file, dependency-free document scanner dialog SDK for the browser. Talks to the local DocuVaultScannerService on Windows.
Maintainers
Readme
DocuVault Scanner
A single-file, dependency-free document-scanner dialog for the browser. Drop it into any web project — a plain HTML page, a server-rendered app, or a modern bundler setup — and capture pages from a connected scanner.
- One file, no jQuery, no build step, no framework required
- UMD — use it as a global (
window.DocuVaultScanner) orimportit - Outputs a single JPEG or a merged multi-page PDF
- Built-in review UI: reorder, re-scan, delete, preview, print, download
How it works. The SDK is the browser side. On the end user's machine it talks to the local DocuVaultScannerService at
http://localhost:42157, which drives the physical scanner. That service is Windows-only — on any other OS the dialog shows a "Windows Required" screen. You host the service installer yourself and point the dialog at it viaserviceInstallerUrl.
Install
Pick whichever fits your stack — all three deliver the same single file.
1. CDN <script> tag (no build step)
<!-- Pin a major (auto-updates within 1.x; no SRI possible since bytes change) -->
<script src="https://cdn.jsdelivr.net/npm/docuvault-scanner@1"></script>For the strongest supply-chain protection, pin an exact version and add a Subresource Integrity hash so a compromised CDN can't serve altered code:
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/docuvault-scanner.min.js"
integrity="sha384-REPLACE_WITH_PUBLISHED_HASH"
crossorigin="anonymous"></script>jsDelivr shows the ready-to-paste
integrityattribute for any exact-version file — use the "SRI" button on the file's page atjsdelivr.com/package/npm/docuvault-scanner. Generate it locally with:cat docuvault-scanner.min.js | openssl dgst -sha384 -binary | openssl base64 -A
2. npm (apps with a bundler — React, Vue, Vite, webpack…)
npm install docuvault-scannerimport DocuVaultScanner from 'docuvault-scanner'
// or: const DocuVaultScanner = require('docuvault-scanner')3. Self-host (locked-down / offline / no external CDN)
Copy docuvault-scanner.js (or the smaller docuvault-scanner.min.js) into your project and
serve it from your own server:
<script src="/assets/docuvault-scanner.min.js"></script>Quick start
The only things you usually need are an installer URL and a result handler:
<script src="https://cdn.jsdelivr.net/npm/docuvault-scanner@1"></script>
<script>
DocuVaultScanner.open({
serviceInstallerUrl: 'https://your-site.com/DocuVaultScannerService.exe',
onComplete: async (file) => {
const fd = new FormData();
fd.append('file', file);
await fetch('/api/upload', { method: 'POST', body: fd });
},
});
</script>PDF output needs no setup. The SDK auto-loads jsPDF from the CDN (version-pinned + SRI-verified) the first time it builds a PDF — you don't add a jsPDF
<script>yourself. To self-host it or reuse a copy already on your page, setjsPdfUrl(or just include your own jsPDF before this script).
Result handler: onComplete or onScan
You must provide exactly one of these (passing both is not supported — onComplete
takes precedence and onScan is ignored).
onComplete(file) — the common choice. Receives the single finished File: a JPEG when the
output is one image, or a merged PDF for multi-page / PDF output. Best when you just want to
upload or save the result.
DocuVaultScanner.open({
serviceInstallerUrl: '…',
onComplete: async (file) => {
const fd = new FormData();
fd.append('file', file);
await fetch('/api/upload', { method: 'POST', body: fd });
},
});onScan(file, blobs) — same finished file, plus the array of per-page image Blobs.
Use it when you need the individual pages (e.g. your own client-side processing) as well as the
combined file.
DocuVaultScanner.open({
serviceInstallerUrl: '…',
onScan: (file, blobs) => {
console.log('combined file:', file.name);
console.log('individual pages:', blobs.length);
},
});Async handlers. If your handler returns a Promise (e.g. an upload), the dialog stays open with a loader until it settles — closing on success, or staying open with an error toast on rejection. Synchronous handlers close the dialog immediately.
All options
Every parameter open() accepts, with its default. All are optional except that you must
provide one result handler (see above).
<script>
DocuVaultScanner.open({
// ── Service / installer ─────────────────────────────────────────────
scannerHost: 'http://localhost:42157', // local service base URL (rarely changed)
serviceInstallerUrl: 'https://your-site.com/DocuVaultScannerService.exe', // shown on the "service offline" screen
osCheck: true, // false = skip the "Windows Required" screen on non-Windows OSes
// ── Dialog appearance / labels ──────────────────────────────────────
title: 'Invoice', // pre-fills the document name field
confirmLabel: 'Upload', // label on the confirm button (e.g. 'Upload', 'Attach')
appearance: 'light', // 'light' | 'dark' | 'auto' (follow OS)
theme: { primary: '#4f46e5', radius: '9px' }, // brand color + corner radius
// ── Default scan settings (the user can still change these) ─────────
defaultSettings: {
colorMode: 'Color', // 'Color' | 'Grayscale' | 'BlackAndWhite'
resolution: 300, // 150 | 300 | 600 (DPI)
source: 'Auto', // 'Auto' | 'Flatbed' | 'Feeder'
output: 'IMAGE', // 'IMAGE' (single JPEG) | 'PDF'
showUI: false, // true = use the scanner's native Windows dialog
},
// Hide settings you don't want users touching. Any of:
// 'device' | 'showUI' | 'colorMode' | 'resolution' | 'source'
lockedSettings: ['source'],
// ── jsPDF override (optional) ───────────────────────────────────────
jsPdfUrl: '', // blank = use bundled <script> or CDN fallback
// ── Result handler (provide ONE — see section above) ────────────────
onComplete: async (file) => { // OR use onScan instead — not both
const fd = new FormData();
fd.append('file', file);
await fetch('/api/upload', { method: 'POST', body: fd });
},
// ── Lifecycle callbacks (optional) ──────────────────────────────────
onClose: () => {}, // dialog dismissed (X / Cancel / Esc)
onError: (err) => { console.error(err); }, // service down, scan failed, unsupported OS, …
});
</script>Offline / no-CDN setup
By default the SDK pulls two things from CDNs: the SDK file itself (if you used the CDN
<script> tag) and jsPDF (auto-loaded the first time a PDF is built). For air-gapped or
locked-down environments, host both yourself and the SDK never touches an external network.
Self-host the SDK — copy
docuvault-scanner.min.jsinto your assets and serve it locally:<script src="/assets/docuvault-scanner.min.js"></script>Self-host jsPDF — download
jspdf.umd.min.js, serve it locally, and point the SDK at it withjsPdfUrl:DocuVaultScanner.open({ serviceInstallerUrl: '/installers/DocuVaultScannerService.exe', jsPdfUrl: '/assets/jspdf.umd.min.js', // no CDN — loaded from your server onComplete: (file) => { /* … */ }, });Alternatively, include your own jsPDF
<script>before the SDK — ifwindow.jspdfalready exists, the SDK uses it and skips loading entirely.
Image-only scans never load jsPDF at all, so if you never produce PDFs you only need step 1.
API
DocuVaultScanner.open(options)→ opens the dialog, returns{ close() }isServiceRunning()→Promise<boolean>(2s timeout, never throws)listDevices()→Promise<Array<{deviceId, name}>>scan(request)→Promise<ScanResponse>(throws onsuccess:false)fetchPageBlob(fileId)→Promise<Blob>blobToBase64(blob)→Promise<string>(data URL)createClient(host)/SCANNER_BASE_URLVERSION→ SDK build version string (e.g.'1.0.3'); handy for bug reports
open() options summary
scannerHost, serviceInstallerUrl, osCheck (default true),
title, confirmLabel, appearance ('light'/'dark'/'auto'),
theme ({ primary, radius }),
defaultSettings (colorMode/resolution/source/output/showUI),
lockedSettings ('device'/'showUI'/'colorMode'/'resolution'/'source'),
jsPdfUrl, onComplete(file) or onScan(file, blobs), onClose(), onError(err).
Build (maintainers)
The source is hand-written and ships as-is; the minified file is generated:
npm install # installs esbuild
npm run build # → docuvault-scanner.min.jsnpm publish runs the build automatically (prepublishOnly).
