Tags
No tags yet
wimp
Web image manipulation — in-browser cropping, templates, and high-quality export. Everything runs locally in your browser; your images never leave the page and nothing is uploaded to a server.
What it does
- Interactive cropping with zoom, pan, rotation, and horizontal/vertical flip, powered by react-easy-crop.
- Built-in templates for common targets (OG image, Twitter/X card,
Instagram square/portrait, Story/Reel, YouTube thumbnail, LinkedIn cover,
avatar, favicon, US passport, and more) — selecting one sets the crop aspect,
output size, and sensible encoder defaults. See
src/templates.ts. - Color adjustments (brightness, contrast, saturation, grayscale, sepia, hue rotate) applied live in the preview and baked into the export from a single shared filter definition, so what you see matches what you get.
- High-quality export to JPEG, WebP, PNG, or AVIF with a quality control, optional long-edge size cap, and a download / copy-to-clipboard result card.
All pixel processing and encoding happen off the main thread in a Web Worker, so the UI stays responsive even on large photos.
Quick start
Requires Node 22+ and npm.
npm install
npm run dev # start the Vite dev serverOpen the printed local URL. Load an image by drag-and-drop, clicking the dropzone, or pasting from the clipboard.
Other scripts
npm run build # type-check then produce a production build
npm run preview # serve the production build locally
npm run typecheck # tsc, no emitKeyboard shortcuts
| Key | Action |
|---|---|
[ / ] |
Rotate -90° / +90° |
h / v |
Flip horizontal / vertical |
0 |
Reset zoom and pan |
Cmd/Ctrl+S |
Export |
How it works
Three deliberately separated layers:
- Interactive UI (main thread, React 19 + React Compiler) — crop, zoom, rotation, flip, and live CSS-filter color preview.
- Pixel processing (Web Worker) — decode, rotate/flip, crop, and resample to the target size. Uses libvips (lanczos3, via wasm-vips) for meaningful downscales when cross-origin isolation is available, otherwise an OffscreenCanvas high-quality draw.
- Encoding (same worker) — jSquash WASM codecs (MozJPEG / WebP / OxiPNG /
AVIF) for real quality control, with
OffscreenCanvas.convertToBlobas a fallback.
For the full design, coordinate model, and file map, see
docs/ARCHITECTURE.md.
Tech stack
- TypeScript, React 19.2 + React Compiler
- Vite 8 (Rolldown / Oxc)
- Tailwind CSS v4 (design tokens in CSS
@theme, no config file) - react-easy-crop for the crop UI
- wasm-vips (libvips) for resampling; jSquash codecs for encoding
The app sets Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy
headers so SharedArrayBuffer is available for the threaded WASM builds.
Documentation
docs/ARCHITECTURE.md— design, data flow, file map.docs/WORKLOG.md— what was built and key decisions.docs/VERIFICATION.md— test evidence.docs/deferred/— intentionally deferred work (background removal, face-aware passport framing, free-form crop, enhancements) and known limitations.