pdfcat is a high-performance command line utilitiy to merge PDF files into a single document without losing quality.
You may be looking for:
β¨ Zero Quality Loss
- Direct PDF object copying (no re-rendering).
- Preserves images, fonts, annotations, and form fields
π Full Control
- Extract ranges, rotate pages, add bookmarks.
- Set custom metadata (title, author, subject, keywords)
- Configurable compression (none, standard, maximum)
π High Performance
- Parallel PDF loading with efficient memory usage
- Optimized for large files
pdfcat currently supports the following architectures:
- x86_64 (64-bit Intel/AMD processors)
- aarch64 (64-bit ARM processors)
git clone https://github.com/pdfcat/pdfcat
cd pdfcat
cargo build --release
sudo cp target/release/pdfcat /usr/local/bin/cargo install pdfcatFor more details see installation script.
bash -c "$(curl -fsSL https://raw.githubusercontent.com/pdfcat/pdfcat/main/scripts/install.sh)"This script will:
- Automatically detect your machine's architecture
- Download and unpack the necessary .tar
- Copy the
pdfcatbinary tousr/local/bin
For more details see installation script.
Ensure your PowerShell execution policy allows (remote) script execution:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUserExecuting the following script will walk you through the installation process (you may need to run this command from an elevated shell):
Invoke-Expression -Command (Invoke-WebRequest -Uri "https://raw.githubusercontent.com/pdfcat/pdfcat/main/scripts/install.ps1" -UseBasicParsing).ContentMerge two PDFs:
pdfcat file1.pdf file2.pdf -o merged.pdfMerge all PDFs in a directory:
pdfcat *.pdf -o combined.pdfAdd bookmarks:
pdfcat chapter*.pdf -o book.pdf --bookmarksExtract specific pages:
pdfcat document.pdf -o excerpt.pdf --pages "1-5,10,15-20"Rotate pages:
pdfcat scan.pdf -o rotated.pdf --rotate 90Set metadata:
pdfcat files*.pdf -o output.pdf \
--title "Combined Report" \
--author "John Doe" \
--subject "Q4 Results"Maximum compression:
pdfcat large*.pdf -o compressed.pdf --compression maximumDry run (validate without creating output):
pdfcat file1.pdf file2.pdf -o test.pdf --dry-runpdfcat [OPTIONS] <FILE>... -o <FILE>
Arguments:
<FILE>... Input PDF files to merge (in order)
Options:
-o, --output <FILE> Output PDF file path
-n, --dry-run Validate inputs without creating output
-v, --verbose Show detailed information
-q, --quiet Suppress non-error output
-f, --force Overwrite existing output without confirmation
--no-clobber Never overwrite existing output
-b, --bookmarks Add bookmarks for each merged document
-c, --compression <LEVEL> Compression level [default: standard]
[possible values: none, standard, maximum]
--title <TEXT> Set title metadata
--author <TEXT> Set author metadata
--subject <TEXT> Set subject metadata
--keywords <TEXT> Set keywords metadata
--continue-on-error Continue if some PDFs fail to load
--input-list <FILE> Read input file list from file
-j, --jobs <N> Number of parallel jobs
--pages <RANGE> Page ranges to extract (e.g., "1-5,10")
--rotate <DEGREES> Rotate pages [possible values: 90, 180, 270]
-h, --help Print help
-V, --version Print version
Merge chapters with bookmarks and metadata:
pdfcat \
chapter1.pdf \
chapter2.pdf \
chapter3.pdf \
references.pdf \
-o dissertation.pdf \
--bookmarks \
--title "My Dissertation" \
--author "Jane Smith" \
--subject "Computer Science" \
--keywords "AI, Machine Learning, Neural Networks"Merge report sections with compression:
pdfcat \
cover.pdf \
executive-summary.pdf \
sections/*.pdf \
appendix.pdf \
-o quarterly-report.pdf \
--compression maximum \
--bookmarksProcess multiple PDFs with error handling:
pdfcat invoices/*.pdf \
-o all-invoices.pdf \
--continue-on-error \
--quiet# Extract first 5 pages from each document
pdfcat doc1.pdf doc2.pdf doc3.pdf \
-o summary.pdf \
--pages "1-5"Create a file list:
echo "report1.pdf" > files.txt
echo "report2.pdf" >> files.txt
echo "report3.pdf" >> files.txtMerge from list:
pdfcat --input-list files.txt -o combined.pdfπ Licensing Note for Test Fixtures
The PDF files located within the
pdfcat/tests/fixturesdirectory are included solely for testing and validation purposes.These files were sourced from various public domains or created specifically for testing structure and complexity. They belong to their respective original owners/creators.
Do not copy, distribute, or reuse these fixture files outside of the pdfcat project's testing context.
Run the test suite:
cargo testRun benchmarks:
cargo benchpdfcat can also be used as a library:
use pdfcat::merge;
use pdfcat::config::{Config, CompressionLevel, Metadata, OverwriteMode};
use std::path::PathBuf;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config {
inputs: vec![
PathBuf::from("file1.pdf"),
PathBuf::from("file2.pdf"),
],
output: PathBuf::from("merged.pdf"),
dry_run: false,
verbose: false,
overwrite_mode: OverwriteMode::Force,
quiet: false,
bookmarks: true,
compression: CompressionLevel::Standard,
metadata: Metadata::default(),
continue_on_error: false,
jobs: None,
page_range: None,
rotation: None,
};
let (document, stats) = merge::merge_pdfs(&config).await?;
println!("Merged {} pages", stats.total_pages);
Ok(())
}Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Licensed under AGPL-3.0.
Built with:
- π Documentation
- π Issue Tracker