A small, no sign-up toolkit for shrinking images, shrinking PDFs, and merging PDFs together. Everything runs through a Python backend and is processed in memory, one request at a time. Nothing is written to a database and nothing is stored on the server after the response goes back.
Built by peterlightspeed - https://peterlightspeed.github.io/portfolio
- Shrink an image - upload a JPG, PNG, WEBP or BMP, choose an output format and quality, optionally cap the width, and get back a smaller file. EXIF rotation is respected so photos from a phone don't come out sideways.
- Shrink a PDF - rebuilds the file's internal structure and, where it is safe to do so, re-encodes oversized embedded photos at a lower quality. Page text is never touched, so documents stay sharp and stay searchable.
- Merge PDFs - combine two or more PDFs into one, in the order they were added.
Every tool shows a before-and-after size comparison and a percentage reduction before you download the result.
The backend does all the real work; the frontend is plain HTML, CSS and JavaScript with no build step and no framework, so anyone can clone the repository and run it immediately. There is no login, no account, and no persistence layer, because none of that serves the actual task: someone with a file that is too big.
- Backend: FastAPI (Python), running on Uvicorn
- Image processing: Pillow
- PDF processing: pikepdf (structural compression and safe image re-encoding) and pypdf (merging)
- Frontend: server-rendered HTML with a Jinja2 template, vanilla CSS and JavaScript - no client-side framework, no bundler
pls-compress/
app/
main.py FastAPI app and routes
config.py Shared limits and constants
services/
image_service.py Image resize, convert, compress
pdf_service.py PDF compress and merge
templates/
index.html The single page the app serves
static/
css/style.css Styling
js/app.js Frontend logic: tabs, drag and drop, fetch calls
requirements.txt
Requires Python 3.10 or newer.
python -m venv .venv
source .venv/bin/activate # on Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn app.main:app --reloadThen open http://127.0.0.1:8000 in a browser.
Images are re-encoded through Pillow with the chosen format and quality. Converting a large PNG screenshot to a JPEG or WEBP at a sensible quality, and capping the width, is usually where most of the savings come from.
PDF compression uses pikepdf (a Python binding for QPDF) to rebuild the file with better internal compression, and separately walks each page's images looking for large, simple RGB or grayscale photos to re-encode at a lower JPEG quality. Each image is re-encoded inside its own try/except block and is only kept if it actually comes out smaller; anything that looks unusual (indexed color, CMYK, or an image with a transparency mask) is left untouched rather than risk corrupting the page. This means the reduction on a text-only PDF will be modest, and the reduction on a PDF full of high-resolution photos will be much larger. That trade-off is intentional: reliability across arbitrary uploaded files matters more than squeezing out a few extra percent.
PDF merging uses pypdf to read each uploaded file and append its pages, in the order the files were provided, into one output file.
- Uploads are capped at 25 MB per file (see
app/config.py). - Up to 20 files can be merged in a single request.
- The PDF tools only accept
application/pdf.
These are defaults chosen to keep a public demo responsive and are
easy to change in app/config.py.
This project is free to explore, learn from, and adapt.