# pdf-rs/pdf: a Rust PDF library with experimental writing

> pdf-rs/pdf is a Cargo workspace for reading, changing and writing PDF files in Rust. Its inspection examples and tests support evaluation, while modification and writing remain explicitly experimental.

**pdf-rs/pdf** — Rust library to read, manipulate and write PDF files.

- Repository: https://github.com/pdf-rs/pdf
- Stars: 1,718 · Forks: 151
- Language: Rust
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/pdf-rs-pdf

## The PDF operations needed in a Rust workspace

pdf-rs/pdf addresses a specific need in Rust applications that work with PDF data as objects rather than merely send a file to an external command. The README describes it as a library to "Read, alter and write PDF files," which makes it relevant to document indexing, metadata handling, page-content processing and tools that inspect or transform PDF structure. Its intended audience is Rust developers who can include a library crate in an application and need direct control over Rust types and error handling.

The README does not provide an API tour, object model, supported PDF feature list or compatibility matrix. It also does not explain whether encrypted PDFs, damaged files, incremental updates or particular PDF versions are supported. Those omissions matter when selecting a document library. The README establishes the intended capabilities, not their completeness. The examples named `content`, `metadata`, `names`, `read` and `text` indicate several inspection paths, but it does not describe their output contracts.

This is a library to investigate for programmatic PDF work, not a general PDF application. The README points to a separate repository for rendering and a minimal viewer, which clarifies the boundary. pdf-rs/pdf is not presented as the complete PDF viewing stack. Its center of gravity is document handling in Rust code.

## Cargo workspace layout and build scope

The repository is a Cargo Workspace with three declared members: `pdf`, `pdf_derive` and `examples`. Its resolver is set to `"2"`. The README explains an important default behavior: only the `pdf` library is built by default because the workspace uses default members. Additional parts must be selected explicitly with the package name. For additional components, the documented selector is `--package=read`, although the workspace also declares a member named `examples`.

That distinction can affect build and troubleshooting workflows. A developer who expects every workspace package to build under the default command should not infer that behavior from a multi-crate workspace. The documented package selector narrows the build, but the README does not explain why it calls the example crate `read` when the top-level workspace member is `examples`. That inconsistency should be checked against `Cargo.toml` before adding the project to a larger build pipeline.

The crate split can still be useful. The core library, derive package and example code are separate workspace members rather than one indivisible directory. Based on the repository layout, a consumer can evaluate the core `pdf` crate without automatically compiling every example. However, the README gives no feature flags, dependency versions, minimum supported Rust version or semantic-version compatibility statement. Those details cannot be inferred from the workspace declaration.

## Running pdf-rs/pdf examples against a PDF

The README does not provide package installation steps, a versioned download or a `Cargo.toml` snippet for adding `pdf` to another application. It points readers to the repository and its examples instead. The documented example runner selects one of five named programs and supplies a PDF path after `--`. This supports work from a repository checkout, but it does not identify the public dependency coordinates or the API needed for application integration.

The README gives this command form:

```bash
cargo run --example {content,metadata,names,read,text} -- <files/{choose a pdf}>
```

The brace-delimited parts are instructions to choose one value and one PDF, not literal command arguments. For example, choosing `content` routes execution to the `content` example. The README does not document each example's standard output, exit codes or failure messages, so an adopter should not build automation around output that has not been inspected in the target environment.

For repository-level validation, the contribution section gives a narrower command that does not require choosing an example:

```bash
cargo test
```

The README says contributors can add PDF files to `tests/files` and see whether they pass. That is the clearest documented first use for an evaluator: place representative documents in the named directory and run the project's test command. The README does not claim that this validates every PDF standard feature or all production workloads.

## What the PDF examples do and do not establish

The five example names define a practical investigation plan. `metadata` appears intended for metadata inspection, `names` for name-related structures, `text` for text access, and `content` for content-oriented processing. The README does not show their source code or output, so it would be unsafe to claim what fields they print, how they traverse a document or which errors they report. The `read` example is also named separately from the others.

The test suite is the strongest documented way to assess behavior. Contributors are invited to add different PDF files to `tests/files` and see whether they pass. This suggests that document compatibility is evaluated through fixtures rather than a published compatibility table. Acceptance should therefore depend on the reader's actual documents, including unusual page structures, fonts or files produced by multiple applications. The README does not name any such compatibility classes.

The examples package is a workspace member, so Cargo can discover examples through the repository's package configuration. The README's invocation uses `cargo run --example` without a package flag. A developer encountering target-selection errors should inspect `Cargo.toml` and the examples package rather than inventing a flag, because the README does not define the target-resolution failure behavior.

## Writing support and realistic adoption limits

The largest limitation is stated directly in the README: "Modifying and writing PDFs is still experimental." That warning applies to two of the library's three headline operations. It is especially important for long-lived documents, compliance workflows or applications in which a malformed write can corrupt an original file. The README does not document atomic writes, rollback, backup handling, recovery after partial output, preservation guarantees or validation of generated PDFs.

Reading has fewer explicit warnings, but the documentation still does not identify supported compression filters, font handling, embedded files, encryption or malformed-file recovery. The examples demonstrate entry points, not a compatibility contract. An application requiring predictable behavior across third-party PDFs would need fixture tests before depending on it.

The absence of GitHub releases also affects adoption planning. There are no published release artifacts listed in the repository information, so the README gives no upgrade path through versioned releases. Integrators would have to decide how to refer to repository revisions or Cargo versions, but the README does not explain a release policy. That does not make the workspace unusable, yet it adds upgrade uncertainty for production consumers.

## Rendering and inspection split into companion repositories

pdf-rs/pdf offers an alternative to an all-in-one PDF suite: put document parsing and manipulation in a Rust library, then add a separate component only when rendering or visual inspection is required. The README identifies two companion projects with different approaches.

The `pdf_render` repository is described as a library for rendering PDFs through Pathfinder, plus a minimal viewer. Its rendering path is separate from pdf-rs/pdf's core document operations. A team that needs visible page output should not assume the `pdf` crate alone supplies a viewer or renderer. It should inspect `pdf_render` as an additional dependency and account for the separate maintenance surface created by this arrangement.

For diagnosis, `inspect-prim` is described as a tool for visualizing a PDF as an interactive hierarchy of primitives. That differs from using the `read`, `text` or `metadata` examples as command-line output. The former is intended for visual structural exploration; the latter are example programs in this repository. The README does not claim feature parity or explain data exchange between the projects. The practical distinction is architectural: core document work, rendering and interactive inspection are separate concerns.

## Maintenance state, license and contribution friction

The repository is not archived, and its last push was on 2026-10-13. That indicates recent repository activity, but it should not be confused with a stable release cadence because no GitHub releases are listed. Maintenance cost is also shaped by the explicit pull request policy. The README tells contributors to create one pull request containing multiple commits. It says that merging multiple pull requests can create conflicts and avoidable friction. It also rejects pull requests whose code or text was not written by the submitter. These restrictive contribution conditions can make external fixes less straightforward than in a conventional repository.

The project is distributed under the MIT license. The repository includes a `LICENSE` file, which is the controlling text to review for the applicable permissions, conditions and disclaimer. This article does not provide legal advice. Engineers should account for the license and notice requirements in their own distribution process.

The README points contributors to Zulip for questions and problems. For adopters, the lack of releases, experimental writer status and limited API documentation should be weighed separately from the recent push. Activity shows that the codebase changed, not that every advertised capability has reached production stability.

## Conclusion

Adopt pdf-rs/pdf for Rust code that needs programmatic PDF inspection or controlled PDF changes, but do not treat its writer as a production default until representative documents pass the library tests. Avoid it if you need an integrated viewer, a Pathfinder rendering stack or documented transactional guarantees. Before integration, run `cargo test` with your PDFs in `tests/files`, confirm the required examples work, and review the MIT `LICENSE`.

## FAQ

### What is pdf-rs/pdf used for?

It is a Rust library for reading, altering and writing PDF files. The repository presents examples for content, metadata, names, reading and text, while warning that modifying and writing PDFs remains experimental.

### How do I run the pdf-rs/pdf examples?

The README uses `cargo run --example` with one example name from `content`, `metadata`, `names`, `read` or `text`, followed by a PDF path. It does not provide a separate installation command or document each example's output.

### Does pdf-rs/pdf include a PDF renderer or viewer?

Not according to the README's project boundaries. It directs users to `pdf_render` for rendering through Pathfinder and a minimal viewer, and to `inspect-prim` for an interactive hierarchy of PDF primitives.

## Sources

- [Issues](https://github.com/pdf-rs/pdf/issues)
- [License: MIT](https://github.com/pdf-rs/pdf/blob/master/LICENSE)
- [pdf-rs/pdf on GitHub](https://github.com/pdf-rs/pdf)
- [README](https://github.com/pdf-rs/pdf/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pdf-rs-pdf
