Getting started
Start with one upload route and one clear decision: inspect first, store later.
Pompelmi is most useful when you treat uploaded files as untrusted input and make a policy decision before persistence or downstream parsing.
If you want the wider architecture first, read Secure file uploads in Node.js: Beyond Extension and MIME Checks before picking a framework-specific path.
Fastest ways to evaluate it
Section titled “Fastest ways to evaluate it”- Want to inspect the verdict UX without sending a file anywhere? Open the browser preview.
- Want a real route with a form and JSON response? Run the Express demo.
- Want the broader example set first? Start with the examples index.
1. Install the core package
Section titled “1. Install the core package”npm install pompelmiThat is enough to scan bytes locally. Framework adapters are optional.
2. Scan one file
Section titled “2. Scan one file”import { readFileSync } from 'node:fs';import { scanBytes, STRICT_PUBLIC_UPLOAD } from 'pompelmi';
const bytes = readFileSync('./package.json');
const report = await scanBytes(bytes, { filename: 'package.json', mimeType: 'application/json', policy: STRICT_PUBLIC_UPLOAD, failClosed: true,});
console.log(report.verdict);console.log(report.reasons);3. Understand the verdict
Section titled “3. Understand the verdict”| Verdict | Meaning | Typical action |
|---|---|---|
clean | No blocking indicators from the configured checks | Continue to storage or downstream processing |
suspicious | Something risky was detected, but not necessarily confirmed malware | Quarantine, manual review, or reject |
malicious | High-confidence match or a policy condition you treat as malicious | Reject and investigate |
4. Pick a first policy
Section titled “4. Pick a first policy”Built-in policy packs cover common starting points:
| Policy | Best for |
|---|---|
STRICT_PUBLIC_UPLOAD | Public or semi-trusted upload endpoints |
CONSERVATIVE_DEFAULT | Balanced default for most server-side upload flows |
DOCUMENTS_ONLY | PDF and Office-oriented intake portals |
IMAGES_ONLY | Avatar, gallery, and image-only routes |
ARCHIVES | ZIP-heavy endpoints when paired with archive guards |
For archive handling, pair the policy with createZipBombGuard() and CommonHeuristicsScanner:
import { composeScanners, createZipBombGuard, CommonHeuristicsScanner } from 'pompelmi';
const scanner = composeScanners( [ ['zipGuard', createZipBombGuard()], ['heuristics', CommonHeuristicsScanner], ], { stopOn: 'suspicious' });5. Choose your integration path
Section titled “5. Choose your integration path”- Secure file uploads in Express
- Secure file uploads in Next.js
- Secure file uploads in NestJS
- Secure file uploads in Fastify
- Secure file uploads in Koa
- Secure file uploads in Nuxt/Nitro
6. Decide how you will store files
Section titled “6. Decide how you will store files”The most common safe sequence is:
- Receive the upload into memory or an isolated temp area.
- Scan bytes and archive structure.
- Reject malicious files immediately.
- Quarantine suspicious files if you need review instead of hard blocking.
- Persist only the files your application is ready to trust.