Inspect untrusted files before storage, not after.

Pompelmi

Open-source core · MIT · Node.js 18+

Inspect untrusted uploads before they reach storage.

Pompelmi gives Node.js teams an application-layer upload boundary. It helps routes compare claimed file metadata with real file content, apply archive controls, flag risky structures, and add optional YARA before bytes land in storage.

Route verdict
Return clean, suspicious, or malicious before bytes become durable state.
Checks
Combine type validation, archive controls, risky structure checks, and optional YARA.
Deployment
Run in-process, keep files local, and add adapters only where the route needs them.

Minimal route decision

Node.js 18+
import { scanBytes, STRICT_PUBLIC_UPLOAD } from 'pompelmi';

const report = await scanBytes(file.buffer, {
  filename: file.originalname,
  mimeType: file.mimetype,
  policy: STRICT_PUBLIC_UPLOAD,
  failClosed: true,
});

if (report.verdict !== 'clean') return rejectUpload(report);

Install with npm install pompelmi, then wire the upload verdict into reject, quarantine, or promote logic.

Do not trust filename or client MIME

Compare claimed metadata with the bytes and structure before the route accepts the file.

Treat archives as their own risk class

ZIP traversal, expansion, entry-count, and nesting controls belong at the upload boundary.

Keep borderline files out of durable storage

Return a verdict the app can reject, quarantine, or promote with full route context intact.

Works with

pompelmi @pompelmi/express-middleware @pompelmi/next-upload @pompelmi/nestjs-integration @pompelmi/fastify-plugin @pompelmi/koa-middleware @pompelmi/cli

Browser preview

Evaluate the verdict flow without sending a file anywhere

This preview is intentionally limited and honest. It reads selected files locally in the browser so developers can inspect the verdict UX, see a few concrete signals, and understand where the real backend integration takes over.

What it shows

  • files stay in the browser and no upload request is sent
  • detected type, extension, and browser-reported MIME side by side
  • basic suspicious signals such as mismatches, risky PDF or SVG content, and the EICAR test string

What real backend integration adds

  • route-specific policy packs and allowlists
  • archive traversal, expansion, entry-count, and nesting controls
  • optional YARA or other scanners plus quarantine and promotion workflows

Where to go next

Use this preview to understand the decision surface, then move to the framework guides or the Express demo when you want the server-side upload path.

Client-side preview only

This widget reads selected files locally. It never uploads them, and it does not claim to run the full backend policy path.

Files stay in your browser for this preview.

Drag files here to preview a verdict

Useful tests: a normal PDF or PNG, a renamed file, or a text file containing the EICAR test string.

What makes this preview useful

  • Try a file whose extension does not match its actual bytes.
  • Try a ZIP to see where the browser preview stops and the server path begins.
  • Try an EICAR test file to confirm how a high-confidence verdict is presented.

Who it is for

Teams that need a real upload boundary

Good fits include public or semi-trusted upload endpoints, privacy-sensitive systems, document-heavy business flows, and product teams that want the upload decision inside the application path rather than behind a generic cloud dependency.

See all use cases

What Pompelmi is not

It is not positioned as a complete antivirus replacement. It is an application-layer control for the upload boundary.

It works well on its own, or alongside YARA, ClamAV, storage isolation, and human review flows when your environment needs deeper detection or post-upload triage.

External proof

Signals that help teams evaluate the project quickly

Pompelmi keeps the product story grounded: open source, practical docs, and public references that let teams inspect the tradeoffs for themselves.

See the full featured page

Translations

English is the maintained source of truth, but translated resources are available.

The public docs and root README stay focused in English. Community-maintained translations help with discovery and onboarding without duplicating the whole site.

Browse translations

Keep going

Pick the next best page for your team

The docs are the canonical integration surface. The blog and comparison pages help with architecture and rollout decisions before the first route ships.

Ship with confidence

Make the upload decision where your application still has context.

That means route-specific policy, better observability, and a cleaner line between "accepted", "blocked", and "quarantine for review".