High‑impact image optimization for developers.
Drop a folder. Get a ZIP. Ship a faster site. That's it.
Leano turns a folder of images into a highly compressed, production‑ready asset bundle in a single pass. Drop a directory of JPG/PNG files, tune quality and output format, and download a ZIP with the converted images — folder structure fully intact.
Built to be fast, transparent, and developer‑friendly. No accounts. No cloud storage. No drama.
- Folder‑aware uploads — drag & drop a whole directory; original structure is preserved in the output ZIP
- Multiple output formats —
WebP,AVIF, or both for maximum browser coverage - Quality control — per‑run quality slider (50–100, default 80)
- Smart concurrency — bounded to avoid CPU saturation; AVIF tuned for fast encodes without visible quality loss
- Aggregate stats — total files, original vs new size, overall savings % at a glance
- Per‑file results table — savings per image, highlighted rows for ≥ 50% wins, error tooltips for anything that went sideways
- Production‑ready ZIP — includes original
.webpfiles unchanged (no double‑encoding, we're not monsters)
| Layer | Tech |
|---|---|
| Framework | Next.js 15 (App Router) |
| Language | TypeScript |
| Styling | Tailwind CSS + Shadcn‑style primitives |
| Icons | Lucide |
| Image processing | sharp (WebP / AVIF) |
| Runtime | Node.js |
| Analytics | Vercel Analytics |
Prerequisites: Node.js LTS, and whatever package manager you have a personality about.
# install
npm install
# run dev server
npm run devOpen http://localhost:3000 and you're in.
- Drop a folder — drag & drop a directory of JPG/JPEG/PNG images onto the dropzone
- Configure — set quality (50–100) and pick
WebP,AVIF, orBoth - Convert — hit Convert and watch the progress bar do its thing
- Review — check aggregate stats and the per‑file table; hover failed rows for error details
- Download — grab the ZIP and drop the optimized assets straight into your project
| Column | Details |
|---|---|
| Filename | Relative path, monospace font, tooltip on truncation |
| Original / New Size | Human‑readable (B / KB / MB), right‑aligned tabular-nums |
| Savings % | ≥ 50% → emerald highlight · grew in size → amber · failed → red badge |
Scrollable with a sticky header — handles large folders without breaking the layout.
Body (multipart/form-data):
| Field | Type | Description |
|---|---|---|
file_{index} |
File blob | Image file |
path_{index} |
string | Relative path |
quality |
integer | 50–100 |
outputFormat |
string | "webp" | "avif" | "both" |
Response (ConversionResponse):
{
success: boolean;
message: string;
zipBuffer?: string; // base64-encoded zip
stats?: {
totalFiles: number;
totalOriginalSize: number; // bytes
totalConvertedSize: number; // bytes
savedBytes: number;
savedPercentage: number; // 0–100
};
fileResults?: Array<{
originalPath: string;
convertedPath: string;
originalSize: number;
convertedSize: number;
success: boolean;
error?: string;
}>;
}Limits: 50 MB max total upload per run (configurable in the API route).
- CLI mode for headless CI/CD pipelines
- Per‑folder aggregate stats
- Toggle to skip already‑optimized assets
- GitHub Action
MIT — use it, tweak it, ship faster sites.