Free, open-source PDF toolkit with 30 professional tools. Self-hosted iLovePDF alternative.
Features • Demo • Quick Start • Tech Stack • Contributing • License
Most online PDF tools are closed-source, riddled with ads, and upload your files to unknown servers. OpenPdf is different:
- 100% Open Source — MIT licensed. Inspect, modify, and deploy it yourself.
- Privacy First — All processing happens on your server. Files are auto-deleted after 15 minutes.
- No Limits — No file size caps, no watermarks, no account required.
- 30 Professional Tools — Everything from merging to OCR in one clean interface.
- Self-Hosted — One
docker-compose upand you're running.
| Tool | Description |
|---|---|
| Merge PDF | Combine multiple PDFs into one with drag-and-drop reordering |
| Split PDF | Split by page ranges, every N pages, or extract specific pages |
| Rotate PDF | Rotate pages 90/180/270 degrees |
| Delete Pages | Remove specific pages from a PDF |
| Reorder Pages | Rearrange page order with drag-and-drop |
| Tool | Description |
|---|---|
| PDF to Word | Convert PDF to editable .docx with formatting preserved |
| PDF to Excel | Extract tables from PDF into .xlsx spreadsheets |
| PDF to PowerPoint | Convert PDF pages to .pptx slides |
| PDF to Images | Export pages as PNG or JPG with configurable DPI |
| Images to PDF | Combine multiple images into a single PDF |
| HTML to PDF | Convert HTML files to PDF documents |
| Word to PDF | Convert .docx documents to PDF |
| Tool | Description |
|---|---|
| Compress PDF | Reduce file size with low/medium/high quality presets |
| Linearize PDF | Optimize for fast web viewing (progressive loading) |
| Flatten PDF | Flatten form fields and annotations |
| Tool | Description |
|---|---|
| Encrypt PDF | AES-256 password protection with owner/user passwords |
| Decrypt PDF | Remove password protection |
| Redact PDF | Permanently black out sensitive text by keyword search |
| Add Watermark | Text watermarks with custom opacity, position, and rotation |
| Sign PDF | Place a signature image on any page |
| Tool | Description |
|---|---|
| OCR PDF | Make scanned PDFs searchable using Tesseract OCR |
| Add Page Numbers | Insert page numbers with configurable position and format |
| Edit Metadata | View and edit title, author, subject, keywords |
| Add Bookmarks | Create table of contents / bookmarks |
| Repair PDF | Fix corrupted or damaged PDF files |
| Tool | Description |
|---|---|
| Compare PDFs | Side-by-side visual diff highlighting differences |
| Extract Text | Pull all text with per-page view and copy button |
| Extract Images | Extract all embedded images with individual/bulk download |
| PDF Info | Detailed file info, metadata, and per-page stats |
| Count Pages | Count pages across one or multiple PDFs |
git clone https://github.com/aymenhmaidiwastaken/OpenPdf.git
cd OpenPdf
cp .env.example .env
docker compose up --build -d
docker compose psOpen http://localhost:3000 in your browser.
Optional health checks:
curl http://localhost:3000/api/v1/health
curl http://localhost:8000/api/v1/healthPrerequisites: Python 3.11+, Node.js 18+, Redis
Backend:
cd backend
pip install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8000Frontend:
cd frontend
npm install
npm run devOpen http://localhost:3000. The frontend proxies API requests to the backend at port 8000.
- Next.js 15 — App Router, Turbopack, server components
- Tailwind CSS v4 — Custom neumorphic design system
- Framer Motion — Page transitions and component animations
- PDF.js — Client-side PDF preview with zoom and navigation
- TypeScript — End-to-end type safety
- FastAPI — Async Python web framework
- PyMuPDF — PDF rendering, text extraction, OCR, comparison
- pypdf — Merge, split, rotate, page manipulation
- pikepdf — Encryption, metadata, linearization, repair
- Celery + Redis — Async job queue for heavy operations
- ReportLab — Watermarks, page numbers, PDF generation
Browser (Next.js) ──> Next.js API Routes (BFF Proxy) ──> FastAPI Backend
│
Celery Worker
│
Redis
Docker Compose runtime:
Browser -> frontend (Next.js, :3000) -> backend (FastAPI, :8000) -> redis + celery
- Next.js API routes proxy to FastAPI — no CORS, backend stays private
- Fast operations run synchronously, heavy ops (OCR, batch) go through Celery
- Temp files stored in
{UPLOAD_DIR}/{job_id}/, auto-cleaned every 15 minutes - Tool plugin architecture — add a new tool by creating one Python file
POST /api/v1/tools/{tool_name} Upload files + process
GET /api/v1/jobs/{job_id}/status Poll job progress
GET /api/v1/jobs/{job_id}/download Download result file
GET /api/v1/jobs/{job_id}/files List all output files
GET /api/v1/jobs/{job_id}/content/* Get file content inline
DELETE /api/v1/jobs/{job_id} Clean up job
GET /api/v1/health Health check
OpenPdf/
├── frontend/
│ └── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── page.tsx # Homepage
│ │ └── tools/[tool]/ # Dynamic tool pages
│ ├── components/ # React components
│ │ ├── home/ # Hero, FeatureGrid, FeatureCard
│ │ ├── tools/ # FileUploader, PdfViewer, OptionPanel
│ │ │ └── results/ # Inline result displays
│ │ ├── layout/ # Navbar, Footer, ThemeProvider
│ │ └── shared/ # Button, Modal, Toast
│ ├── hooks/ # useFileUpload, useJobPolling
│ ├── lib/ # tools-config, api-client, utils
│ └── types/ # TypeScript interfaces
├── backend/
│ ├── main.py # FastAPI application
│ ├── config.py # Settings (pydantic-settings)
│ ├── routers/ # API route handlers
│ ├── services/ # Tool registry, file/job management
│ ├── tools/ # 30 tool implementations
│ │ ├── base.py # Abstract base tool class
│ │ ├── merge.py
│ │ ├── compress.py
│ │ └── ... # One file per tool
│ └── tasks/ # Celery app + workers
├── scripts/
│ ├── generate_demo_pdf.py # Create demo PDF for testing
│ ├── take_screenshots.py # Automated screenshot capture
│ └── create_gif.py # Generate demo GIF
├── docker-compose.yml
├── .env.example
└── README.md
frontend/Dockerfilebuilds the production Next.js container.frontend/.dockerignoreexcludes local artifacts from image build context.docs/contributions/docker-full-stack-startup-fix.mddocuments the Docker startup fix contribution.
- Create a new file in
backend/tools/:
from pathlib import Path
from tools.base import BaseTool
class MyNewTool(BaseTool):
name = "my-new-tool"
description = "What this tool does"
category = "manipulation" # or conversion, optimization, security, content, analysis
is_async = False
def execute(self, input_files: list[Path], options: dict, output_dir: Path) -> list[Path]:
# Your logic here
output_path = output_dir / "result.pdf"
# ... process files ...
return [output_path]- Add the tool config in
frontend/src/lib/tools-config.ts - That's it — the backend auto-discovers tools, and the frontend uses the dynamic
[tool]route.
| Variable | Default | Description |
|---|---|---|
REDIS_URL |
redis://localhost:6379/0 |
Redis connection URL |
UPLOAD_DIR |
/tmp/openpdf |
Temp file storage directory |
MAX_FILE_SIZE |
52428800 (50 MB) |
Maximum upload file size in bytes |
BACKEND_HOST |
0.0.0.0 |
Backend bind host |
BACKEND_PORT |
8000 |
Backend bind port |
NEXT_PUBLIC_API_URL |
http://localhost:8000 |
Backend URL for frontend proxy |
INTERNAL_API_URL |
http://backend:8000 |
Internal frontend proxy target for Docker networking |
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-tool) - Commit your changes (
git commit -m 'Add amazing tool') - Push to the branch (
git push origin feature/amazing-tool) - Open a Pull Request
- Added a production frontend container and wired it into
docker-compose.ymlso Docker now serves port3000. - Fixed frontend API proxy routing using
INTERNAL_API_URLso/api/v1/*resolves to backend correctly in Docker. - Added
frontend/.dockerignoreto keep local build artifacts out of image context. - Added a detailed contribution write-up at
docs/contributions/docker-full-stack-startup-fix.md.
- New PDF tools (batch processing, PDF/A conversion, form filling)
- UI/UX improvements
- Performance optimizations
- Internationalization (i18n)
- Test coverage
- Documentation
This project is licensed under the MIT License — see the LICENSE file for details.
You are free to use, modify, and distribute this software for any purpose, including commercial use.
If you find OpenPdf useful, please consider giving it a star on GitHub.




