@venomous-maker/dmvic-file-reader
v1.0.0
Published
Isomorphic (Node + browser) OCR reader that extracts structured data from Kenyan DMVIC motor insurance certificates supplied as PDF or image, powered by tesseract.js.
Maintainers
Readme
@venomous-maker/dmvic-file-reader
Isomorphic OCR reader that extracts structured data from Kenyan DMVIC (Digital Motor Vehicle Insurance Certificate) documents supplied as a PDF or an image — on both the backend (Node) and the frontend (browser).
Powered by tesseract.js for OCR and
pdf.js for PDF rasterization, with
built-in watermark removal tuned for these certificates (they overlay
diagonal "DUPLICATE" / "FILE COPY" / repeating "INSURANCE CERTIFICATE"
watermarks that otherwise wreck OCR).
Companion to
dmvic-ts, the TypeScript client for the DMVIC API.
Install
npm install @venomous-maker/dmvic-file-readertesseract.js and pdfjs-dist are regular dependencies. On Node, PDF
rendering and image binarization additionally need the native canvas, installed
automatically as an optional dependency:
npm install @napi-rs/canvas # only if it did not install automaticallyQuick start
import { DmvicFileReader } from '@venomous-maker/dmvic-file-reader';
const reader = new DmvicFileReader();
// Accepts a path (Node), Buffer/Uint8Array, ArrayBuffer, Blob/File (browser),
// a data: URL, or an http(s) URL — PDF or image, auto-detected.
const { certificate, text, pages } = await reader.read('./Certificate-C27605244.pdf');
console.log(certificate);
// {
// certificateNo: 'C27605244',
// policyHolder: 'Simon Kithome',
// policyNo: 'MOR-0701-1-2026 (TPO)',
// commencingDate: '20/07/2026 ; 12:19 EAT',
// expiring: '18/08/2026',
// registrationNo: 'KVT676T',
// chassisNumber: 'NZE-65T65T',
// coverType: 'PRIVATE CAR',
// insurer: 'AKI / Bima Yangu'
// }
await reader.close(); // free the tesseract workerBrowser
import { DmvicFileReader } from '@venomous-maker/dmvic-file-reader';
const reader = new DmvicFileReader();
input.addEventListener('change', async () => {
const file = input.files[0]; // a File/Blob
const { certificate } = await reader.read(file);
render(certificate);
});Everything runs client-side — no file ever leaves the browser.
Extracted fields (IDmvicCertificate)
| Field | Example | Notes |
|---|---|---|
| certificateNo | C27605244 | Recovered from the file name when masked on-page |
| policyHolder | Simon Kithome | |
| policyNo | MOR-0701-1-2026 (TPO) | |
| commencingDate | 20/07/2026 ; 12:19 EAT | As printed |
| expiring | 18/08/2026 | |
| registrationNo | KVT676T | |
| chassisNumber | NZE-65T65T | |
| coverType | PRIVATE CAR | ECoverType |
| insurer | AKI / Bima Yangu | |
Unresolved fields are null — the result shape is always complete.
Options
await reader.read(input, {
languages: 'eng', // tesseract language(s)
dpi: 300, // PDF render DPI (higher = sharper, slower)
preprocess: true, // binarize to strip the watermark (recommended)
threshold: 100, // 0-255 darkness cutoff for binarization
fileName: 'Certificate-C27605244.pdf', // for cert-number recovery
logger: (m, p) => console.log(m, p), // progress
});Force a specific reader with reader.readPdf(input, opts) or
reader.readImage(input, opts).
Architecture
The package is built from small, injectable contracts (interfaces), each with a default implementation you can swap:
| Interface | Default implementation | Responsibility |
|---|---|---|
| IFileReader | ImageReader, PdfReader | Public read contract |
| IOcrEngine | TesseractOcrEngine | Image → text |
| IPdfRasterizer | PdfjsRasterizer | PDF → per-page images |
| IImagePreprocessor | BinarizePreprocessor | Watermark removal |
| — | DmvicCertificateParser | Text → structured fields |
ImageReader and PdfReader both extends AbstractReader, which owns the
shared pipeline (normalize input → images → OCR → parse). Inject your own
collaborators to customize any stage:
import {
DmvicFileReader,
type IOcrEngine,
} from '@venomous-maker/dmvic-file-reader';
class MyOcrEngine implements IOcrEngine { /* ... */ }
const reader = new DmvicFileReader({ ocrEngine: new MyOcrEngine() });Errors
All failures throw a typed DmvicReaderError with a machine-readable code
(UNSUPPORTED_INPUT, PDF_RENDER_FAILED, OCR_FAILED, PREPROCESS_FAILED,
PARSE_FAILED, MISSING_DEPENDENCY, ENVIRONMENT_UNSUPPORTED).
Scripts
npm run build # dual CJS + ESM build (tsup) with .d.ts
npm test # jest test suite
npm run typecheck # tsc --noEmit
npm run docs # typedocLicense
ISC © Morgan Okumu
