Free online PDF tools — merge, split, compress, convert, rotate, watermark, and more. Built with React, TypeScript, and Tailwind CSS.
Live: https://pdfghar.in
| Tool | Type | How It Works |
|---|---|---|
| Merge PDF | Client-side | pdf-lib |
| Split PDF | API | LibreOffice API |
| Compress PDF | API | LibreOffice API |
| Rotate PDF | Client-side | pdf-lib |
| Watermark PDF | Client-side | pdf-lib |
| Unlock PDF | Client-side | pdf-lib |
| PDF to JPG | Client-side | pdfjs-dist (renders pages to canvas) |
| JPG to PDF | Client-side | pdf-lib (embeds images) |
| Word to PDF | API | LibreOffice headless |
| PDF to Word | API | Python (pdf2docx) |
| PPT to PDF | API | LibreOffice headless |
| PDF to PPT | API | Python (pdf2image + python-pptx) |
| Excel to PDF | API | LibreOffice headless |
| PDF to Excel | API | Python (pdfplumber + openpyxl) |
| HTML to PDF | API | LibreOffice headless |
| PDF to PDF/A | API | LibreOffice headless |
Client-side tools run entirely in the browser — no files leave the user's device. API tools send files to a self-hosted LibreOffice API backend for processing.
- Frontend: React 18, TypeScript, Vite, Tailwind CSS, shadcn/ui
- PDF Processing (client): pdf-lib, pdfjs-dist
- PDF Processing (server): LibreOffice headless, Python (pdf2docx, pdfplumber, openpyxl)
- Backend API: Node.js + Express (LibreOffice wrapper), Flask (Python PDF conversions)
- Database/Storage: Supabase (job tracking, file storage)
- Deployment: AWS Amplify (frontend), AWS Lightsail (API backend via Docker)
├── src/
│ ├── pages/ # All tool pages + Index, About, Admin, NotFound
│ ├── components/ # Header, Hero, ToolCard, AdminDashboard, UI components
│ ├── hooks/ # use-toast
│ └── lib/ # supabase, databaseService, pdfOperations,
│ # conversionUtils, libreofficeApi, cleanupService,
│ # fileExpirationService
├── public/ # Logo, brand-logo, robots.txt, sitemap.xml
├── libreoffice-api/ # Self-hosted conversion API (Docker)
│ ├── server.js # Express API (LibreOffice + proxy to Python)
│ ├── python-service/ # Flask API (pdf2docx, pdfplumber, pdf2image)
│ ├── docker-compose.yml # Redis, LibreOffice API, Python API, Nginx
│ └── nginx.conf # Reverse proxy config
└── supabase/
└── setup.sql # Database schema
- Node.js 18+
- npm
# Clone the repo
git clone https://github.com/your-username/we-love-pdf.git
cd we-love-pdf
# Install dependencies
npm install
# Create environment file
cp .env.example .env
# Edit .env with your keys (see Environment Variables below)
# Start dev server
npm run devThe app runs at http://localhost:8080.
Create a .env file in the project root:
VITE_SUPABASE_URL=your-supabase-project-url
VITE_SUPABASE_ANON_KEY=your-supabase-anon-key
VITE_LIBREOFFICE_API_URL=https://your-api-domain.com
VITE_LIBREOFFICE_API_KEY=your-api-key
VITE_ADMIN_PASSWORD=your-admin-passwordClient-side tools (Merge, Rotate, Watermark, Unlock) work without any env vars. API-based tools require Supabase and the LibreOffice API to be configured.
npm run buildOutput goes to dist/. The build uses code-splitting — each page is a separate chunk loaded on demand.
- Connect your GitHub repo in the AWS Amplify Console
- Amplify auto-detects
amplify.ymlfor build settings - Add environment variables in App settings → Environment variables
- Add a SPA rewrite rule in Rewrites and Redirects:
- Source:
</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|woff2|ttf|map|json|webp|xml|mjs)$)([^.]+$)/> - Target:
/index.html - Type:
200 (Rewrite)
- Source:
- Connect your custom domain (
pdfghar.in) in Domain Management
# On your Lightsail instance
cd ~/libreoffice-api
# Configure environment
cat > .env << 'EOF'
API_KEY=your-api-key
ALLOWED_ORIGINS=https://pdfghar.in,http://localhost:8080
PYTHON_API_URL=http://python-api:3001
EOF
# Start services
docker compose up -dThis starts: Redis, LibreOffice API (Node), Python API (Flask), and Nginx.
If the frontend is served over HTTPS, the API must also be HTTPS. Otherwise browsers block mixed-content requests. Set up SSL on your API server using Let's Encrypt/Certbot with nginx.
| Command | Description |
|---|---|
npm run dev |
Start dev server on port 8080 |
npm run build |
Production build to dist/ |
npm run preview |
Preview production build locally |
npm run lint |
Run ESLint |
Private project. All rights reserved.