A privacy-first image & PDF toolbox that runs entirely in your browser.
No uploads. No accounts. No tracking. OpenDocs Studio ships 24 production-ready tools for working with images and PDFs β every operation happens locally on your device using the Canvas API, pdf-lib, pdf.js and Web Crypto. Your files never leave your machine.
| π§° 24 tools | 12 image Β· 12 PDF |
| π 100% client-side | Files are processed in-memory, never transmitted |
| π Free for everyone | No sign-in, no limits, no data collection |
| β‘ Instant | No round-trip to a server β results download immediately |
PREVIEW.mp4
DEMO.mp4
π Visit this: π’OpenDocs Studio
- Open Tools in the sidebar (or navigate to
/tools) - Pick a tool and drop in your file(s) β the input form is generated automatically from the tool's definition
- Click Run Tool β the result downloads instantly (multi-file results are bundled into a single ZIP)
| Tool | What it does | Key options |
|---|---|---|
| Image Format Converter | Re-encode one or more images cleanly to JPG, PNG, WebP, GIF, BMP, AVIF or ICO β results download individually or as a ZIP. | JPG, PNG, WebP, GIF, BMP, AVIF or ICO output with quality control |
| Image Compressor | Compress one or more images by quality percentage or target file size β results download individually or as a ZIP. | Format (auto / JPG / PNG / WebP), quality 1β100 (PNG is compressed via color reduction) |
| Background Eraser | Erase photo backgrounds with a real AI matting model that runs 100% on your device β nothing is ever uploaded. | AI model (medium = best quality / small = fastest), new background (transparent / white / black / custom color), output format (PNG / WebP); AI files ship via npm run fetch:models |
| Custom Album Creator | Design a photo album visually β pick a template (grid, polaroid, film strip and more), style it, and preview it live. | Tile width / height, columns (1β12), spacing, cover / stretch tile fit, background color, output format |
| Add Watermark / Overlay | Overlay a graphic and/or text branding onto an image β pick any font and color for the text. | 9 position anchors, overlay opacity, overlay scale (% of image width), text label, font size, hex color β the overlay image is optional, so text-only watermarks work too |
| Adjustments & Enhancement | One-pass photo tune-up β brightness, contrast, saturation, hue, color temperature, sharpening, blur, sepia and grayscale. | Slider controls for brightness, contrast, saturation, hue, color temperature, sharpen, blur, sepia, grayscale + output format (keep / PNG / JPG / WebP) |
| EXIF Metadata Stripper | Remove EXIF / camera-location / timestamp metadata. Re-encodes the image (PNG output is lossless). | Output format (PNG, JPG, WebP, keep) |
| Image Crop | Cut a rectangular region out of an image. | Pixel-precise left / top offsets + crop width / height |
| Image Resize | Visually rescale an image, exact size or fit-inside box, with aspect-ratio lock and a live preview. | Width / height (0 = auto), fit mode (stretch / fit-inside), resampling algorithm (bicubic, Lanczos, bilinear, nearest, area β mapped to the closest canvas smoothing mode; nearest gives true pixel-art-friendly nearest-neighbor) |
| Batch Image Renamer | Sanitize and rename many images at once β returns a ZIP of the renamed files. | Prefix, suffix, sequential numbering with zero-padding β returns a ZIP |
| Image Flip / Mirror | Mirror one or more images horizontally or vertically (or both) β transparency is preserved and the output format is up to you. | Direction (horizontal / vertical / both), output format (keep / PNG / JPG / WebP) β transparency preserved |
| Base64 Converter | Encode images into Base64 (data URI or raw) for HTML/CSS embedding, or decode a Base64 / data-URI text file back into its original file. | Data-URI or raw Base64 output for HTML/CSS embedding; decoding strips data-URI prefixes / line breaks, accepts the URL-safe alphabet, and sniffs PNG / JPG / WebP / GIF / BMP / AVIF / ICO / SVG / PDF |
| Tool | What it does | Key options |
|---|---|---|
| PDF Compressor | Compress one or more PDFs by quality percentage or target file size β results download individually or as a ZIP. | Quality % (1β100) or target size (KB / MB) |
| Images to PDF | Turn images into a PDF, one image per page. | Accepts multiple images; each page is sized to its image |
| PDF to Images | Render every page to an image. | PNG or JPG, 50β300 DPI (default 150) β returns a ZIP |
| PDF Watermark | Stamp a logo image and/or text onto every page β added as real PDF content, so the original text stays selectable. | 9 position anchors, opacity, overlay scale (% of page width), text label, font, size and color; the overlay image is optional |
| Protect PDF | Lock a PDF with a password and set what readers may do. | AES-256 (or legacy RC4), user + optional owner password, permission presets (all / read-only / no printing) |
| Unlock PDF | Remove a password while keeping text selectable. | Enter the user or owner password; legacy AES-128 locks are unlocked by re-rendering pages |
| PDF Splitter | Extract page ranges into separate PDFs. | Ranges like 1-3,5,7-9 (bounds-checked) β returns a ZIP |
| PDF Merger | Combine several PDF files into a single document. | Optional document-title metadata |
| PDF Page Rotator | Fix sideways scans. | 90Β° / 180Β° / 270Β°, applied to all pages or a single page |
| PDF Page Deleter | Delete specific pages from a PDF by specifying page numbers or ranges. | Comma-separated page numbers (1-based) |
| PDF Page Reorderer | Reorder pages in a PDF by specifying a new page order. | Comma-separated 1-based page numbers |
| PDF Page Numberer | Add page numbers to all pages of a PDF with customizable position, font size, and color. | Position, start number, font size, color |
This isn't a policy promise β it's how the code works:
- Files are read with the browser File API and processed entirely in memory
- PDF page manipulation uses pdf-lib; page rendering uses pdf.js (
pdfjs-dist) - Image processing uses the Canvas API; EXIF data is dropped by re-encoding
- There is no backend, no database and no analytics on your files β once dependencies are installed, the app even works offline
The suite is registry-driven β the UI builds itself from data, so a new tool needs no UI code:
- Define it in
src/tools/registry.tsβ id, name, group, icon, description, file inputs (multi-file and optional inputs supported) and form fields (number / select / text with defaults, min / max / step) - Implement it as an async processor in
src/tools/imageProcessors.ts,imageBatchProcessors.tsorpdfProcessors.tswith the signature(files, params, onProgress) => ToolOutput[] - Dispatch it with a single
caseinrunTool()(src/tools/index.ts)
That's it β ToolRunner.tsx automatically renders the form, validates required inputs, shows live progress, surfaces errors as toasts, and downloads single outputs directly or bundles multi-output results as a ZIP.
Option A β one click (Windows): double-click open.bat. It installs dependencies on first run, starts the dev server if it isn't already running, and opens your browser at http://localhost:5173.
Option B β manual:
npm install
npm run devThen open http://localhost:5173 and click Tools in the sidebar.
For production: npm run build produces a fully static site in dist/ β deployable to any static host (Vercel, Netlify, GitHub Pages, a plain nginx box...) since there is no backend to configure.
| Layer | Technology |
|---|---|
| UI framework | React 19 + TypeScript |
| Build tool | Vite |
| Styling | Tailwind CSS |
| State / routing | Zustand Β· React Router v7 |
| PDF manipulation | pdf-lib (merge, split, rotate, compress, watermark, images β PDF) |
| PDF rendering | pdfjs-dist (PDF β canvas β PNG/JPG; legacy-lock unlock fallback) |
| PDF security | @pdfsmaller/pdf-encrypt & pdf-decrypt (AES-256 / RC4 protect + unlock via Web Crypto) |
| Bundling | JSZip (multi-file tool outputs) |
| Image processing | Canvas API |
| AI background removal | @imgly/background-removal (ISNet matting via ONNX Runtime Web, self-hosted models) |
src/
βββ tools/ # β
The tool engine
β βββ registry.ts # All 29 tool definitions (inputs + form fields)
β βββ types.ts # Shared tool contracts (ToolDefinition, ToolFile...)
β βββ helpers.ts # File pickers, downloads, ZIP, param helpers
β βββ index.ts # runTool() dispatcher
β βββ imageProcessors.ts # resize Β· crop Β· compress Β· convert Β· watermark Β· EXIF
β βββ imageBatchProcessors.ts # batch rename Β· album grid
β βββ pdfProcessors.ts # merge Β· split Β· rotate Β· imagesβPDF Β· compress Β· render Β· watermark Β· protect Β· unlock
βββ components/
β βββ tools/ToolRunner.tsx # Auto-generated tool UI (form, progress, download)
β βββ ui/ Β· layout/ # Reusable UI kit + Sidebar/Header
βββ pages/
β βββ ToolsPage.tsx # Tool catalog (/tools) + runner route (/tools/:toolId)
β βββ Dashboard Β· Files Β· ... # App shell pages
βββ public/tools-icons/ # One icon per tool
The same shell also includes a lightweight document workspace: a file manager with upload/search/organize, a document viewer, and basic text, image, spreadsheet, presentation and PDF editors β all browser-local, with dark mode throughout. The tools suite above is the headline feature; these editors cover quick everyday edits.
| Command | Purpose |
|---|---|
npm run dev |
Start the dev server on port 5173 |
npm run build |
Type-check, then production build to dist/ |
npm run preview |
Serve the production build locally |
npm run type-check |
TypeScript check only |
npm run lint |
ESLint (zero-warning policy) |
npm run fetch:models |
One-time download of the Background Eraser AI models into public/models/ (full offline support) |
| Problem | Fix |
|---|---|
| Browser opens but can't connect | The dev server window (from open.bat) must stay open β if it was closed, run open.bat again |
| Port 5173 already in use | Change the port in vite.config.ts, or close the other Vite instance |
| Odd behavior after pulling changes | rm -rf node_modules package-lock.json && npm install |
| Type or lint errors | npm run type-check and npm run lint point to the exact lines |
MIT β free for personal and commercial use.
Contributions welcome! Tool contributions are especially easy: one registry entry + one processor function = a new tool with a full UI (see the developer guide above).