Skip to main content

pdfxz

Simple PDF compression from your terminal.

pdfxz is a small command-line tool for compressing PDF files with Ghostscript.

It gives you two ways to work:

  • Interactive TUI — easy to use with menus and buttons.
  • CLI — great for scripts, batch jobs, and automation.
┌───────────────────────────────────────────────────────────────┐
│                         P D F X Z                             │
│                  PDF Compression Utility                      │
├───────────────────────────────────────────────────────────────┤
│ INPUT                                                         │
│ [ ~/Documents/papers                          ] [ Browse... ] │
│                                                               │
│ OUTPUT                                                        │
│ [ ~/Documents/compressed                      ] [ Browse... ] │
│                                                               │
│ QUALITY                                                       │
│ ▰▰▰▯▯  Balanced                                               │
│                                                               │
│                     [ Compress PDFs ]                         │
└───────────────────────────────────────────────────────────────┘

Why pdfxz?

  • Easy to use: run pdfxz and use the interactive interface.
  • Works without the TUI: use simple commands for scripts and automation.
  • Compress one file or many: process a PDF or an entire folder.
  • Five clear quality levels: choose how much compression you want.
  • Safe by default: your original PDF is never overwritten.
  • Safe batch processing: one bad PDF does not stop the other files.
  • Automatic cleanup: incomplete output files are removed after failure or cancellation.
  • Built-in file browser: use Browse... instead of typing long paths.
  • Clear progress: see which files finished and how much space was saved.
  • Linux, macOS, and Windows: works wherever Python and Ghostscript are available.

Installation

1. Install pdfxz

pip install pdfxz

To install from a local checkout:

pip install .

pdfxz requires Python 3.10 or newer.

2. Install Ghostscript

pdfxz uses Ghostscript to do the actual PDF compression, so Ghostscript must be installed separately.

Ubuntu / Debian

sudo apt install ghostscript

Fedora

sudo dnf install ghostscript

Arch Linux

sudo pacman -S ghostscript

macOS

Using Homebrew:

brew install ghostscript

Windows

Download and install Ghostscript from:

https://www.ghostscript.com/releases/gsdnld.html

On Windows, pdfxz looks for gswin64c, gswin32c, or gs on PATH. You can also set PDFXZ_GS_PATH when Ghostscript is installed somewhere else.

Check that Ghostscript works:

gs --version

On Windows, you can use:

gswin64c --version

If Ghostscript is missing, pdfxz shows a clear error instead of a confusing failure.


How to Use

Interactive TUI

The easiest way to start:

pdfxz

Choose your input PDF or folder, choose an output folder if needed, select a quality level, and press Compress PDFs.

Browse files and folders

The TUI includes Browse... buttons for both input and output.

You can select:

  • a PDF file
  • an input folder
  • an output folder

You do not need to type the complete path yourself.

v0.2.1: fewer settings, less to worry about

The TUI no longer asks you to manually configure:

  • Recursive scanning
  • Create missing directories
  • Overwrite existing files

These are handled automatically:

  • folders are always scanned recursively
  • missing output folders are created automatically
  • existing output files are never overwritten
  • when a filename already exists, pdfxz creates a new unique filename instead

The CLI still provides explicit options for these settings.

File sizes

The TUI always displays file sizes in MB for a consistent view.

Useful TUI shortcuts

  • Esc — cancel a running batch
  • q — quit
  • n — start a new batch from the report screen

Long filenames are shortened on screen. Select a report row to see the full path.


CLI

The CLI is useful when you want commands that can be reused in scripts.

Compress one PDF

pdfxz paper.pdf

Creates:

paper_compressed.pdf

Choose the output file

pdfxz input.pdf -o output.pdf

You can also use the positional form:

pdfxz input.pdf output.pdf

Compress a folder

pdfxz ~/papers -o ~/compressed

Choose a quality level

pdfxz paper.pdf -q balanced

Scan subdirectories

pdfxz ~/papers -o ~/compressed -q strong -r

Create missing output directories

pdfxz input.pdf -o ~/new/path/output.pdf -p

Never start the TUI

For scripts and automation:

pdfxz input.pdf --no-tui

When INPUT is supplied, pdfxz already runs non-interactively. --no-tui is useful when you want a script to fail immediately instead of opening the interactive interface by mistake.


Common CLI Options

Option What it does
-o, --output PATH Set the output PDF or directory
-p, --parents Create missing output directories
-q, --quality LEVEL Choose the compression level
-r, --recursive Scan subdirectories too
--overwrite Allow an existing output file to be replaced
--no-tui Never launch the interactive interface

The available quality values are maximum, high, balanced, strong, and maximum-compression.


Compression Levels

pdfxz has five explicit compression profiles. The default is Balanced.

Level Best for Quality Compression
maximum Archival copies Highest Lowest
high Good quality with smaller files Very high Moderate
balanced Everyday use Good Moderate
strong Smaller files Lower Strong
maximum-compression Smallest possible files Lowest Highest

The profiles use different image downsampling settings. Higher compression generally means smaller files and more visible quality loss.

Important

There is no fixed compression percentage.

A scanned PDF with many images may become much smaller, while a text-only PDF may change very little.


Safe Output and File Naming

pdfxz is designed to keep your files safe.

Your original PDF is never overwritten

The compressor refuses to use the same file as both input and output. The original input is never modified or deleted.

Existing files are protected

In the CLI, an existing output is not replaced unless you explicitly use:

--overwrite

In the TUI, existing outputs are never overwritten; pdfxz creates a unique filename instead.

For example:

report.pdf
report_compressed.pdf
report_compressed (2).pdf
report_compressed (3).pdf

Batch folders stay organized

When scanning folders recursively, pdfxz keeps the original folder structure in the output directory. This prevents files with the same name in different folders from accidentally replacing each other.

Failed or cancelled jobs are cleaned up

If Ghostscript fails or you cancel a compression, pdfxz removes any partial output file. Your input PDF remains untouched.

Invalid PDFs are detected

pdfxz does not trust the .pdf extension alone. It also checks for the %PDF- file signature.


Development

Clone the repository:

git clone https://github.com/pythyn/pdfxz
cd pdfxz

Create a virtual environment:

python -m venv .venv

Activate it.

Linux / macOS:

source .venv/bin/activate

Windows:

.venv\Scripts\activate

Install the development dependencies:

pip install -e ".[dev]"

The project uses pytest and pytest-asyncio for development and testing.

Testing

Run the full test suite:

pytest

The tests cover the main parts of the project, including:

  • TUI startup and interaction
  • CLI parsing and execution
  • PDF compression
  • cancellation and cleanup
  • compression profiles
  • file scanning and PDF validation
  • formatting and utility functions

The test suite uses a small fake Ghostscript executable, so the tests do not need a real Ghostscript installation.

The v0.2.1 tests also verify that the old TUI settings for recursive scanning, missing directories, and overwrite behavior are no longer present.

Project Structure

pdfxz/
├── src/pdfxz/
│   ├── app.py           # Interactive TUI
│   ├── cli.py           # Command-line interface
│   ├── compressor.py    # Ghostscript compression
│   ├── profiles.py      # Compression profiles
│   ├── scanner.py       # PDF discovery and validation
│   ├── workers.py       # Batch processing
│   ├── models.py        # Result and state models
│   ├── formatting.py    # Output formatting helpers
│   └── utils.py         # Paths, Ghostscript, and safety helpers
│
├── tests/
│   ├── test_app.py
│   ├── test_cli.py
│   ├── test_compressor.py
│   ├── test_profiles.py
│   ├── test_scanner.py
│   ├── test_utils.py
│   ├── test_formatting.py
│   └── fixtures/
│       └── fake_gs.py
│
├── CHANGELOG.md
├── LICENSE
└── pyproject.toml

The TUI and CLI use the same underlying compression and batch-processing code, which keeps behavior consistent between both modes.

License

MIT License.

See LICENSE for the full license text.

Metadata

Release files for pdfxz 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pdfxz 0.2.1
File Size Uploaded
pdfxz-0.2.1.tar.gz 34.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pdfxz 0.2.1
File Interpreter ABI Platform
pdfxz-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 66.2 kB

Release files / pdfxz-0.2.1.tar.gz

Download URL pdfxz-0.2.1.tar.gz
Size 34.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e3eb830d305065748a19a4190ff9f83143f066dfc66b80b1e63cee5c1246ea01
BLAKE2b-256 checksum
How to use checksums
ecd66bba7598ccd9bc1b146771277169342e6511b17f47c083120e744a6cc001
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Release files / pdfxz-0.2.1-py3-none-any.whl

Download URL pdfxz-0.2.1-py3-none-any.whl
Size 31.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c5773a2842359aa1b60f2bb22f843a934e164e406a883728ee4b99e98af7434
BLAKE2b-256 checksum
How to use checksums
a8251b2431c43ff08d5ed0810c1a742a97447aea217496a38b84cd3f4ce65083
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.0

2 release files

0.3.0

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page