pompelmi v1.0.0

A minimal Node.js wrapper around ClamAV that scans any file and returns a plain string: Clean, Malicious, or ScanError. No daemons. No cloud. No native bindings.

npm install pompelmi

Install

pompelmi requires Node.js ≥ 14 and ClamAV installed on the host system.

Install the npm package
npm install pompelmi
Install ClamAV (macOS)
brew install clamav && freshclam
Install ClamAV (Linux)
sudo apt-get install -y clamav clamav-daemon && sudo freshclam
Install ClamAV (Windows)
choco install clamav -y
pompelmi checks automatically whether ClamAV is already installed before running any install command. If clamscan is already in PATH, the installation step is skipped entirely. You never need to run it more than once.

Updating the Virus Database

After installing ClamAV, download virus definitions with freshclam:

freshclam          # macOS / Windows
sudo freshclam     # Linux
pompelmi checks automatically whether the virus database file is already present on disk before running freshclam. If the database exists, the update step is skipped. No need to run it manually more than once.

See Quickstart for the full step-by-step guide.

Example

const pompelmi = require('pompelmi');

async function scanUpload(filePath) {
  const result = await pompelmi.scan(filePath);

  if (result === 'Malicious') {
    throw new Error('Upload rejected: malware detected');
  }
  if (result === 'ScanError') {
    console.warn('Scan incomplete — treating file as untrusted');
  }

  return result; // "Clean" | "Malicious" | "ScanError"
}

scanUpload('./uploads/document.pdf')
  .then(r => console.log('Scan result:', r))
  .catch(err => console.error(err.message));

Features

One functionCall pompelmi.scan(path) and await a string. No config objects, no callbacks. Predictable resultsAlways one of "Clean", "Malicious", or "ScanError". Easy to switch on.
Cross-platformWorks on macOS, Linux, and Windows wherever ClamAV is available. No daemon requiredUses clamscan directly. No clamd socket, no background process to manage.
Single dependencyOnly cross-spawn for reliable subprocess handling across platforms. Exit-code mappedClamAV exit codes are mapped directly. No stdout parsing, no regex.

Documentation