PDF tools that stay in your browser.
Merge, split, convert, and protect documents — fast, private, and open source.
| Private by default | Core tools run entirely in the browser via Web Workers — your files never leave your machine in Live Demo Mode. |
| Dual-mode | Use the hosted demo instantly, or connect a local FastAPI backend for OCR, Office export, and deep compression. |
| Modern stack | React 19, TypeScript, Tailwind v4, and pdf-lib — built to extend, not to lock you in. |
flowchart TB
subgraph demo ["Live Demo Mode · GitHub Pages"]
A[Browser] --> B[Web Workers + pdf-lib]
B --> C[Merge · Split · Rotate · Protect · …]
end
subgraph power ["Local Power Mode · localhost"]
A --> D[FastAPI backend]
D --> E[OCR · PDF→Office · Deep compress]
end
| Mode | Where it runs | Best for |
|---|---|---|
| Live Demo | GitHub Pages, 100% client-side | Everyday PDF edits, no install |
| Local Power | Your machine + FastAPI backend | OCR, DOCX/XLSX export, Ghostscript compression |
Always available — no backend, no upload
- Merge, split, extract, delete & reorder pages
- Rotate, flatten, fill & sign, add text & images
- Password protect & unlock
- JPG / PNG → PDF, Markdown → PDF
- Watermark (and more in the registry)
Local Power Mode — requires the backend
- PDF → Word (DOCX)
- PDF → Excel / PowerPoint
- OCR (Tesseract)
- Deep compress (Ghostscript / PyMuPDF)
Requires Docker Desktop (or Docker Engine + Compose).
git clone https://github.com/edvardhov/pdeefy.git
cd pdeefy
docker compose up -dOpen http://localhost:5173/ — frontend and backend (OCR, Office export, deep compression) are ready. The app auto-detects the backend at http://localhost:8000/api/health.
Stop the stack:
docker compose downProduction-style local build (static frontend via nginx on port 4173, no hot reload):
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --buildgit clone https://github.com/edvardhov/pdeefy.git
cd pdeefy
npm install
npm run devcd backend
python3.11 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000The app auto-detects the backend at http://localhost:8000/api/health. Override the URL in Settings if needed.
Full backend setup: backend/README.md
The live demo runs entirely in the browser for core tools. Run docker compose up -d (backend only is enough) to unlock Local Power Mode from the hosted site — the app polls http://localhost:8000/api/health from your browser. Works in Chrome, Edge, and Firefox; Safari may block HTTPS → http://localhost mixed content.
| Layer | Tech |
|---|---|
| Frontend | Vite · React 19 · TypeScript · Tailwind CSS v4 · Shadcn/ui |
| PDF (client) | pdf-lib · Web Workers · pdfjs-dist |
| Backend | FastAPI · PyMuPDF · python-docx · pytesseract |
The app version lives in package.json (0.1.0). The frontend embeds it at build time; the backend reads the same value from package.json (or APP_VERSION in Docker).
See CHANGELOG.md for release notes.
- Update
versioninpackage.jsonand add an entry toCHANGELOG.md. - Commit and push to
main. - Tag and push — this creates a GitHub Release via
.github/workflows/release.yml:
git tag v0.1.0
git push origin v0.1.0The tag must match package.json exactly (e.g. tag v0.1.0 ↔ "version": "0.1.0").
Pushes to main deploy to GitHub Pages via .github/workflows/deploy.yml. Set the repository Pages source to GitHub Actions.
Logo SVGs (light / dark icon + wordmark lockups) live in public/. The app uses the full lockup on large screens and the square icon on mobile, swapping with the active theme.