Professional image toolbox — 10 tools, zero uploads, 100% in your browser.
Crop · Resize · Compress · Convert · Rotate · Flip · Adjust · Effects · Thumbnail · Info
Privacy-first · No sign-up · No limits · All processing via Canvas API — your files never leave the device.
- Preview
- Why Hydra1mage
- Features
- Tech Stack
- Architecture
- Design System
- Project Structure
- Getting Started
- Scripts
- Deployment & SEO
- Contributing
- Roadmap
- License & Credits
Tool groups (Edit / Optimize / Enhance / Inspect), live search, drag-and-drop zone and persistent preview. Pick any tool — your image follows you.
Cropper.js powered, free-form + presets (1:1, 4:3, 16:9, 9:16, 21:9), live dimension readout and full-resolution export.
PNG, JPG, WebP, AVIF, GIF, BMP, TIFF, ICO, ICNS, SVG, PDF. Quality control and correct ICO headers.
Blur, sharpen, emboss, noise, vignette, grayscale, sepia, pixelate, duotone, posterize, edge-detect, oil paint, invert and more.
6 presets (Natural / Bright / Warm / Cool / Vivid / Dramatic) + 8 sliders (exposure, temperature, tint, highlights, shadows, vibrance, gamma, sharpness) with live preview.
Dominant palette (click to copy HEX), brightness distribution, quick stats, file / dimension / technical breakdown — computed locally.
| # | Tool | Route | Highlights |
|---|---|---|---|
| 1 | Crop | /crop |
Cropper.js, ratio presets, live preview |
| 2 | Resize | /resize |
Locked aspect, presets 25%–200% & 512/1024/1920 |
| 3 | Compress | /compress |
Smart binary-search to target KB + manual slider |
| 4 | Convert | /convert |
11 formats, quality control |
| 5 | Rotate | /rotate |
Presets 90/180/270/-90 + free angle -180→180 |
| 6 | Flip | /flip |
Horizontal / Vertical / Both |
| 7 | Adjust | /adjust |
8 sliders + 6 presets, hold-to-compare |
| 8 | Effects | /effects |
15 effects, search + category pills |
| 9 | Thumbnail | /extract-thumbnail |
5 YouTube resolutions, preview + download |
| 10 | Info | /info |
Palette, histogram, EXIF & efficiency |
Global: Floating dock (xl only) — History (undo/redo/jump, branching, persist), File (Save/Copy/Clear), Source (GitHub), System (Theme).
| Layer | Choice | Notes |
|---|---|---|
| Framework | Next.js 16 | App Router, Turbopack, per-route metadata |
| UI | React 19 + TypeScript 5 | Strict, atomic ImageContext |
| Styling | Tailwind CSS 4 | CSS vars --bg-* --accent |
| Icons | Lucide React | Tree-shakable, 340+ icons via lucide-static CDN |
| Canvas | Canvas API | core.ts — no WASM |
| Crop | Cropper.js 1.5 | CDN, lazy-loaded |
| Analytics | Vercel Analytics | Privacy-friendly |
| Deploy | Vercel | Static, edge |
Split from 1116-LOC image-utils.ts into focused facade:
lib/image/
core.ts # loadImage, ObjectURL lifecycle, downloadBlob
geometry.ts # dimensions, aspect, orientation
compress.ts # binary-search quality
convert.ts # 11 formats, ICO header
adjust.ts # 8-prop pipeline
effects.ts # 15 filters
info.ts # 100px sample, dominant colors, brightness
history.ts # ImageHistory (MAX 20, branching, persist)
index.ts # barrel
- Single
historyRef: ImageHistory— no scattered states - Atomic
{file, url}withuseRef+useEffectrevoke handleFileSelect / Clear / Undo / Redo / Jump+Ctrl+Z/Ctrl+Y
useImageLoader— safe dimensionsuseCanvasPreview— canvas lifecycle
navigation/ nav-items.ts, Logo.tsx, DesktopTopBar.tsx, MobileNav.tsx, FloatingDock.tsx (68px, timeline)
shared/ ToolLayout.tsx, ToolHeader.tsx, ImagePreview.tsx, CanvasPreview.tsx
tools/ AdjustTool.tsx, EffectsTool.tsx, InfoTool.tsx, ...
- Tokens
globals.css:--bg-primary / --bg-elevated,--text-primary / -muted,--border,--accent - Theme: blocking
ThemeScriptin<head>+matchMedialistener — no FOUC - Cards:
rounded-[20px](dock18px),border,backdrop-blur - Dock:
68pxwide,6pxpadding,HISTORY/FILE/SOURCE/SYSTEMpills, timeline panel300px - Type:
Space Grotesk+JetBrains Mono
Hydra1mage/
├── public/ (favicon.svg, robots.txt, sitemap.xml, screenshots/)
├── src/
│ ├── app/ (layout.tsx, page.tsx, globals.css, crop/ resize/ compress/ convert/ rotate/ flip/ adjust/ effects/ extract-thumbnail/ info/)
│ ├── components/ (navigation/, shared/, tools/, DropZone.tsx, Sidebar.tsx, ThemeInit.tsx)
│ ├── hooks/ (useImageLoader.ts, useCanvasPreview.ts)
│ └── lib/ (image/*, image-context.tsx, format.ts)
├── eslint.config.mjs
├── vitest.config.mjs
└── package.json
- Node.js 18+ (20 recommended)
- npm / yarn / pnpm
git clone https://github.com/onyxax/Hydra1mage.git
cd Hydra1mage
npm install
npm run devnpm run build # 11 static routes, typecheck
npm run start| Script | Purpose |
|---|---|
npm run dev |
Next dev (Turbopack) |
npm run build |
Production build |
npm run start |
Serve build |
npm run lint |
ESLint |
- Vercel —
vercel.json, static output - Per-route
layout.tsxmetadata (OG1200×630, Twitter, canonical) - Root
layout.tsx:metadataBase,robots,verification.google,JSON-LDWebApplicationwith 10-itemfeatureList - Assets:
robots.txt,sitemap.xml,favicon.svg
PRs welcome!
git checkout -b feature/my-feature
git commit -m "feat: my feature"
git push origin feature/my-feature
# open PR against mainKeep it client-side, follow var(--*) tokens and ToolHeader/ToolCard primitives.
- Batch queue for resize/compress
- WASM AVIF tuning
- Export presets & history polish
- Cmd+K palette
- PWA offline
- License: MIT
- Author: onyxax — https://guns.lol/onyxax
- Crop engine: Cropper.js
Made with care — open source, privacy-first. Star the repo if you like it.




