npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

docuvault-scanner

v1.0.3

Published

Single-file, dependency-free document scanner dialog SDK for the browser. Talks to the local DocuVaultScannerService on Windows.

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) or import it
  • 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 via serviceInstallerUrl.

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 integrity attribute for any exact-version file — use the "SRI" button on the file's page at jsdelivr.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-scanner
import 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, set jsPdfUrl (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.

  1. Self-host the SDK — copy docuvault-scanner.min.js into your assets and serve it locally:

    <script src="/assets/docuvault-scanner.min.js"></script>
  2. Self-host jsPDF — download jspdf.umd.min.js, serve it locally, and point the SDK at it with jsPdfUrl:

    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 — if window.jspdf already 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 on success:false)
  • fetchPageBlob(fileId)Promise<Blob>
  • blobToBase64(blob)Promise<string> (data URL)
  • createClient(host) / SCANNER_BASE_URL
  • VERSION → 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.js

npm publish runs the build automatically (prepublishOnly).