
Baoyu Compress Image
Shrink PNG, JPEG, and WebP assets locally with automatic compressor choice so landing pages and apps load faster without a separate SaaS image tool.
Install
npx skills add https://github.com/jimliu/baoyu-skills --skill baoyu-compress-imageWhat is this skill?
- Bun-driven CLI with sips (macOS), cwebp, ImageMagick, or Sharp backends
- Output formats: WebP, PNG, and JPEG with configurable quality
- Batch and recursive folder processing with optional JSON reporting
- Supported inputs: PNG, JPG, JPEG, WebP, GIF, TIFF
- Reports input/output sizes and compression ratio per file
Adoption & trust: 21.1k installs on skills.sh; 20.9k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Frontend Designanthropics/skills
Vercel React Best Practicesvercel-labs/agent-skills
Remotion Best Practicesremotion-dev/skills
Vercel Composition Patternsvercel-labs/agent-skills
Develop Userscriptsxixu-me/skills
Next Best Practicesvercel-labs/next-skills
Journey fit
Primary fit
Image compression is part of building and polishing UI deliverables before launch, not a growth analytics task. Frontend asset pipelines and page weight optimization fit the frontend subphase when you prepare icons, heroes, and marketing imagery.
Common Questions / FAQ
Is Baoyu Compress Image safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Baoyu Compress Image
#!/usr/bin/env bun import { existsSync, statSync, readdirSync, unlinkSync, renameSync } from "fs"; import { basename, dirname, extname, join, resolve } from "path"; import { spawn } from "child_process"; type Compressor = "sips" | "cwebp" | "imagemagick" | "sharp"; type Format = "webp" | "png" | "jpeg"; interface Options { input: string; output?: string; format: Format; quality: number; keep: boolean; recursive: boolean; json: boolean; } interface Result { input: string; output: string; inputSize: number; outputSize: number; ratio: number; compressor: Compressor; } const SUPPORTED_EXTS = [".png", ".jpg", ".jpeg", ".webp", ".gif", ".tiff"]; async function commandExists(cmd: string): Promise<boolean> { try { const proc = spawn("which", [cmd], { stdio: "pipe" }); return new Promise((res) => { proc.on("close", (code) => res(code === 0)); proc.on("error", () => res(false)); }); } catch { return false; } } async function detectCompressor(format: Format): Promise<Compressor> { if (format === "webp") { if (await commandExists("cwebp")) return "cwebp"; if (await commandExists("convert")) return "imagemagick"; return "sharp"; } if (process.platform === "darwin") return "sips"; if (await commandExists("convert")) return "imagemagick"; return "sharp"; } function runCmd(cmd: string, args: string[]): Promise<{ code: number; stderr: string }> { return new Promise((res) => { const proc = spawn(cmd, args, { stdio: ["ignore", "ignore", "pipe"] }); let stderr = ""; proc.stderr?.on("data", (d) => (stderr += d.toString())); proc.on("close", (code) => res({ code: code ?? 1, stderr })); proc.on("error", (e) => res({ code: 1, stderr: e.message })); }); } async function compressWithSips(input: string, output: string, format: Format, quality: number): Promise<void> { const fmt = format === "jpeg" ? "jpeg" : format; const args = ["-s", "format", fmt, "-s", "formatOptions", String(quality), input, "--out", output]; const { code, stderr } = await runCmd("sips", args); if (code !== 0) throw new Error(`sips failed: ${stderr}`); } async function compressWithCwebp(input: string, output: string, quality: number): Promise<void> { const args = ["-q", String(quality), input, "-o", output]; const { code, stderr } = await runCmd("cwebp", args); if (code !== 0) throw new Error(`cwebp failed: ${stderr}`); } async function compressWithImagemagick(input: string, output: string, quality: number): Promise<void> { const args = [input, "-quality", String(quality), output]; const { code, stderr } = await runCmd("convert", args); if (code !== 0) throw new Error(`convert failed: ${stderr}`); } async function compressWithSharp(input: string, output: string, format: Format, quality: number): Promise<void> { const sharp = (await import("sharp")).default; let pipeline = sharp(input); if (format === "webp") pipeline = pipeline.webp({ quality }); else if (format === "png") pipeline = pipeline.png({ quality }); else if (format === "jpeg") pipeline = pipeline.jpeg({ quality }); await pipeline.toFile(output); } async function compress( compressor: Compressor, input: string, output: string, format: Format, quality: number ): Promise<void> { switch (compressor) { case "sips": await compressWithSips(input, output, format, quality); break; case "cwebp": if (format !== "webp") { await compressWithSharp(input, output, format, quality); } else { await compressWithCwebp(input, output, quality); } break; case "imagemagick": await compressWithImagemagick(input, output, quality); break; case "sharp": await compressWithSharp(input, output, format, quality); break; } } function getOutputPath(input: string, format: Format, keep: boolean, customOutput?: string): string { if (customOutput) return resolve(customOutput); const dir = dirname(input