WebPify is a lightning-fast, privacy-first browser-based image compressor. It converts your images to the highly optimized WebP format entirely locally using WebAssembly (WASM).
Because all processing happens directly in your browser via Web Workers, your images never leave your device, ensuring 100% privacy and a responsive user interface.
- 🔒 Privacy-First: 100% in-browser conversion. No server uploads required.
- ⚡ Blazing Fast: Powered by WebAssembly (
@jsquash/webp) for near-native encoding speeds. - 🧵 Non-Blocking UI: Heavy lifting is offloaded to a dedicated Web Worker, keeping the app smooth.
- 🎛️ Fine-Grained Control: Adjust quality (1-100) with a slider or use quick presets (Low/Medium/High).
- 📊 Real-Time Metrics: Instantly see input/output sizes, savings ratio, and conversion duration.
- 🛑 Cancellable Operations: Abort in-flight conversions instantly if you change your mind.
- 🧪 Built-in Benchmarking: Test performance across different image sizes directly in the app.
- 🖱️ Intuitive UX: Seamless drag-and-drop and file picker support.
-
Install dependencies:
pnpm install
-
Start the development server:
pnpm dev
-
Open in your browser:
- Main App: http://localhost:3000
- Benchmark Suite: http://localhost:3000/benchmark
pnpm build
pnpm start- Framework: Next.js (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- Package Manager: pnpm
- WebP Encoder:
@jsquash/webp(WASM) - Processing: Dedicated Web Workers
- Input: You select or drag-and-drop an image.
- Read: The UI reads the file into memory as an
ArrayBuffer. - Dispatch: The buffer and your quality settings are sent to a background Web Worker.
- Process: The Worker decodes the image and encodes it to WebP using WebAssembly.
- Return: The Worker sends back the compressed bytes and performance metrics.
- Result: The UI updates with a preview, stats, and a download button.
WebPify includes a dedicated /benchmark page to test encoding performance across three synthetic test cases:
- Small:
800 × 600 - Medium:
1920 × 1080 - Large:
3840 × 2160
For each resolution, the benchmark reports:
- Input vs. Output size
- Compression savings (%)
- Worker encode time vs. Wall-clock time
app/
├── page.tsx # Main converter UI
└── benchmark/page.tsx # Benchmark suite
components/
├── upload-shell.tsx # Drag & drop / Converter component
└── benchmark-runner.tsx # Benchmark execution UI
lib/
├── worker-client.ts # Worker bridge & cancellation logic
└── worker-protocol.ts # Typed request/response definitions
workers/
└── webp.worker.ts # WASM encoding Web Worker
plans/ # Project documentation & roadmaps
├── webp-wasm-roadmap.md
├── release-checklist.md
└── ...
- Zero Data Collection: Core conversion runs locally. We do not collect raw image data.
- Telemetry: Any future telemetry will be strictly privacy-safe (see
plans/privacy-safe-telemetry.md).
This repository uses Husky (.husky/pre-commit) to enforce quality and security:
pnpm check:secrets: Scans staged files to prevent accidental commits of tokens/keys.pnpm lint: Ensures code quality.
(Emergency bypass: git commit --no-verify - not recommended)
WebPify is automatically deployed to GitHub Pages via GitHub Actions (.github/workflows/deploy-pages.yml).
Workflow Steps:
- Installs dependencies via pnpm.
- Runs linters.
- Builds a static export (
out/). - Deploys the artifact to GitHub Pages.
Setup Instructions:
- Go to your repository Settings → Pages.
- Under Build and deployment, set Source to GitHub Actions.
- The workflow will automatically handle the
NEXT_PUBLIC_BASE_PATHdepending on whether it's a project page or a user page.
VS Code launch configurations are provided in .vscode/launch.json.
If pnpm dev fails with a NODE_OPTIONS preload path error, clear the stale debug injection:
unset NODE_OPTIONS
pnpm dev