# How to Use the `detect-pdf` CLI for PDF Classification

> Easily classify PDFs with the detect-pdf CLI. Learn how this tool categorizes documents into TextBased, Scanned, or Mixed using simple heuristics. Improve your PDF handling today.

- Repository: [Firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector)
- Tags: how-to-guide
- Published: 2026-09-01

---

**The `detect-pdf` CLI classifies PDFs into TextBased, Scanned, or Mixed categories using heuristics that measure extractable text versus image content.**

The `detect-pdf` command-line tool is part of the [firecrawl/pdf-inspector](https://github.com/firecrawl/pdf-inspector) repository, a Rust-based library for analyzing PDF documents. This guide explains how to install, run, and integrate the tool for reliable PDF classification.

## What `detect-pdf` Does

The tool categorizes any PDF into one of three classifications based on content analysis:

| Classification | Description |
| -------------- | ----------- |
| **TextBased** | PDF contains extractable, machine-readable text (e.g., exported from Word or generated from HTML) |
| **Scanned** | PDF consists primarily of page images with minimal or no extractable text |
| **Mixed** | PDF contains both extractable text layers and scanned image content |

This classification helps downstream tools decide whether to apply OCR, direct text extraction, or hybrid processing pipelines.

## Installation and Basic Usage

### Build from source

```bash
git clone https://github.com/firecrawl/pdf-inspector.git
cd pdf-inspector
cargo build --release --bin detect-pdf

```

The binary will be available at `target/release/detect-pdf`.

### Basic classification command

```bash
detect-pdf path/to/document.pdf

```

**Example output:**

```

TextBased

```

## CLI Options and Output Formats

### JSON output (`--json`)

Add `--json` to receive structured output suitable for scripting:

```bash
detect-pdf --json path/to/document.pdf

```

**Example output:**

```json
{
  "classification": "Mixed",
  "confidence": 0.87,
  "details": {}
}

```

### Detailed analysis (`--analyze`)

Add `--analyze` to include diagnostic details about how the classification was determined:

```bash
detect-pdf --analyze --json path/to/document.pdf

```

**Example output:**

```json
{
  "classification": "Scanned",
  "confidence": 0.95,
  "details": {
    "image_pages": 12,
    "text_ratio": 0.03,
    "tiled_scan": true,
    "garbage_text_upgrade": true
  }
}

```

The `tiled_scan` flag indicates the detector found evidence of tiled scanning patterns common in digitized documents. The `garbage_text_upgrade` flag shows when low-quality extracted text triggered a promotion from `Mixed` to `Scanned`.

## Architecture and Source Code

Understanding the implementation helps debug unexpected classifications and extend the tool.

### Entry point: [`src/bin/detect_pdf.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/detect_pdf.rs)

The CLI binary lives in [`src/bin/detect_pdf.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/detect_pdf.rs). It:

- Parses arguments using **clap**
- Calls `process_pdf_with_options` from the library
- Formats results as plain text or JSON

### Core detection: [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs)

The [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) module implements the classification heuristics:

- **Text extraction rate**: Measures how much alphanumeric text can be extracted from content streams
- **Image analysis**: Inspects page objects for raster images and detects tiled-scan patterns
- **Mixed-mode logic**: Combines signals and applies a garbage-text upgrade rule that promotes `Mixed` to `Scanned` when extracted text falls below 50% alphanumeric

### Public API: [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs)

The [`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) file exposes `process_pdf_with_options()`, the same function the CLI uses. This design allows embedding the classifier in other Rust projects or FFI bindings.

### Supporting modules

| File | Purpose |
| ---- | ------- |
| [`src/text_quality.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/text_quality.rs) | Computes **alphanumeric ratios** and text quality metrics |
| `src/extractor/*` | Low-level PDF parsing for fonts, content streams, and image objects |

## Programmatic Usage in Rust

Import `pdf-inspector` as a library for custom workflows:

```rust
use pdf_inspector::process_pdf_with_options;
use pdf_inspector::ProcessOptions;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let opts = ProcessOptions {
        json: true,
        analyze: true,
        ..Default::default()
    };

    let result = process_pdf_with_options("path/to/document.pdf", opts)?;
    println!("{}", result);
    Ok(())
}

```

The `ProcessOptions` struct mirrors CLI flags:

| Field | Type | Description |
| ----- | ---- | ----------- |
| `json` | `bool` | Emit JSON instead of plain text |
| `analyze` | `bool` | Include detailed diagnostic fields |

## Integration with `pdf2md`

The `detect-pdf` tool shares its core library with the `pdf2md` binary in the same repository. Classification results drive processing strategy:

- **TextBased** → Direct text extraction without OCR
- **Scanned** → Full OCR pipeline
- **Mixed** → Hybrid approach extracting text layers and OCR-ing image regions

This architecture prevents wasted computation on already-readable documents.

## Summary

- The `detect-pdf` CLI provides fast, accurate PDF classification into **TextBased**, **Scanned**, or **Mixed** categories
- Use `--json` for programmatic consumption and `--analyze` for debugging classification decisions
- The underlying Rust library ([`src/lib.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs)) exposes `process_pdf_with_options()` for custom integrations
- Detection heuristics in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) combine text ratio, image analysis, and tiled-scan detection
- Source files: [`src/bin/detect_pdf.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/bin/detect_pdf.rs) (CLI), [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) (logic), [`src/text_quality.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/text_quality.rs) (metrics)

## Frequently Asked Questions

### What Rust version is required to build `detect-pdf`?

The `firecrawl/pdf-inspector` repository uses Rust 2021 edition features. Build with Rust 1.70 or later to ensure compatibility with dependencies such as `pdf-extract` and `tesseract` bindings.

### Can `detect-pdf` handle password-protected PDFs?

No. The tool does not implement decryption logic. Pre-process encrypted PDFs with `qpdf --decrypt` or similar tools before classification, as the underlying `src/extractor/*` modules expect readable content streams.

### How accurate is the Mixed vs. Scanned distinction?

The `garbage-text upgrade` rule in [`src/detector.rs`](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) promotes borderline cases to `Scanned` when alphanumeric content falls below 50%. This conservative approach reduces false positives for OCR pipelines but may over-classify low-quality text PDFs. Use `--analyze` to review the `text_ratio` field and tune thresholds if you fork the detector.

### Is there a Python or Node.js binding available?

Not officially. The repository provides only Rust APIs. Community bindings would need to wrap `process_pdf_with_options()` via PyO3 or napi-rs. For Python workflows, consider shelling out to the CLI or using the classification output to conditionally invoke Python OCR libraries.