CLI tool
ropensci/pdftools avatar
ropensci/pdftools

pdftools wraps poppler so R can read a PDF as text, metadata or a bitmap

Text Extraction, Rendering and Converting of PDF Documents

554 stars71 forksC++NOASSERTION

At a glance

What is it?
pdftools is an R package that extracts text, table of contents, metadata, fonts and rendered pages from PDF files, using the poppler C++ interface through Rcpp rather than the glib based Rpoppler package, which was the portability problem that motivated it. It installs from CRAN on Windows and Mac, needs the poppler development library on Linux, and its newest release is from 2022.
Who is it for?
Adopt pdftools if you work in R and need to pull text, metadata or page images out of PDF files without shelling out to a command line tool. Do not expect it to extract tables, because the documentation is explicit that a PDF has no notion of a table and that extracting tabular data is a separate problem.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 54 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem with searching a scientific literature

The introduction states the motivation plainly. Scientific articles are typically locked away in PDF format, a format designed primarily for printing but not so great for searching or indexing. The pdftools package allows extracting text and metadata from PDF files in R.

What that buys you is specific. From the extracted plain text you could find articles discussing a particular drug or species name, without having to rely on publishers providing metadata, or on pay-walled search engines.

That is a corpus problem, not a single document problem. A researcher with three hundred papers and a question about one compound has to get the text out of all of them before the question can be asked, and a format that was designed for a page layout does not make that easy.

The package also produces structured output, not just a string. There is a table of contents extractor, an information function for metadata such as the author, the creation date or tags, a fonts function, and attachments. The table of contents is described as looking pretty in JSON, which matters if you are feeding it into something else.

Why not Rpoppler, and what the C++ interface buys

The package overlaps with an earlier one, and the difference is the reason this package exists.

The Rpoppler package by Kurt Hornik does the same job. The main motivation behind developing pdftools was that Rpoppler depends on glib, which does not work well on Mac and Windows. The pdftools package uses the poppler C++ interface together with Rcpp, which results in a lighter and more portable implementation.

That is the whole design decision. Both packages are thin wrappers over poppler, but one reaches it through glib and the other through the C++ API, and the second is the one that installs cleanly on a Mac.

For a user, this shows up as an installation difference rather than an API difference. On Windows and Mac the binary packages install directly from CRAN with no compilation. On Linux you need the poppler development library, because the source build compiles against it. The package ships the C++ code in the src directory and the R interface in the R directory, with a configure script that is where the platform specific poppler detection happens.

Installation, and the one platform that needs a system library

On Windows and Mac the binary packages can be installed directly from CRAN:

r
install.packages("pdftools")

Installation on Linux requires the poppler development library. On Debian or Ubuntu that is:

bash
sudo apt-get install libpoppler-cpp-dev

If you want to install the package from source on MacOS you need brew:

bash
brew install poppler

And on Fedora:

bash
sudo yum install poppler-cpp-devel

So the cost of pdftools is one system library, and it is a development library rather than a runtime one, which is what lets the CRAN binaries work without it on the two platforms where binaries are provided.

The package is published on CRAN with a version badge, and the repository carries a DESCRIPTION file, a NAMESPACE, a NEWS file for the changelog, a man directory for the documentation pages, a tests directory, and both a LICENSE and a LICENSE.md. The repository topics name the stack plainly: pdf-files, pdf-format, poppler, poppler-library, r, r-package, rstats and text-extraction.

pdf_text returns one string per page

The most important function is pdf_text, which returns a character vector of length equal to the number of pages in the PDF, with each string holding the plain text of that page.

r
library(pdftools)
download.file("http://arxiv.org/pdf/1403.2805.pdf", "1403.2805.pdf", mode = "wb")
txt <- pdf_text("1403.2805.pdf")

# first page text
cat(txt[1])

# second page text
cat(txt[2])

Returning a vector of pages rather than one blob is the design decision that matters downstream, because it keeps the page boundary in the data. A document that has a running header on every page, or a two column layout, is still page addressable, and when you are extracting a corpus you can index by page and cite a page number.

The other extraction functions follow the same shape. pdf_toc gives the table of contents, the section headers a reader would show in a menu, and it serialises cleanly:

r
# Table of contents
toc <- pdf_toc("1403.2805.pdf")

# Show as JSON
jsonlite::toJSON(toc, auto_unbox = TRUE, pretty = TRUE)

And the metadata and font functions are the same pattern:

r
# Author, version, etc
info <- pdf_info("1403.2805.pdf")

# Table with fonts
fonts <- pdf_fonts("1403.2805.pdf")

The ?pdftools manual page gives the overview of the main utilities.

Rendering a page to a bitmap array

Beyond text, pdftools can render pages as images. The poppler library provides all the functionality to implement a complete PDF reader, including graphical display of the content, and in R you use pdf_render_page to render a page into a bitmap that can be stored as a png or a jpeg.

r
# renders pdf to bitmap array
bitmap <- pdf_render_page("1403.2805.pdf", page = 1)

# save bitmap image
png::writePNG(bitmap, "page.png")
webp::write_webp(bitmap, "page.webp")

The rendered result is a bitmap array, not a file, so the writing step is done by whichever package you prefer. The example uses png and webp, and that is the useful pattern: the rendering is separated from the encoding, so the same array can go out as a png, a jpeg or a webp without re-rendering.

This is the part of the package that reaches past the text layer into the page layout, and it is what makes the package usable for a scanned document that has no text at all, since a rendered image can be fed to an OCR engine instead.

Tables are the thing it cannot do

The limitations section is honest in a way most package documentation is not.

Data scientists are often interested in data from tables, and unfortunately the PDF format is pretty dumb and does not have a notion of a table, unlike HTML for example. Tabular data in a PDF file is nothing more than strategically positioned lines and text, which makes it difficult to extract the raw data with pdftools.

So the fallback is to extract the page text and parse it yourself, which the documentation says is possible with some creativity:

r
txt <- pdf_text("http://arxiv.org/pdf/1406.4806.pdf")

# some tables
cat(txt[18])
cat(txt[19])

The dedicated package for this is tabulizer, also from rOpenSci, which is dedicated to extracting tables from PDF and includes interactive tools for selecting tables. The catch is that tabulizer depends on rJava and therefore requires additional setup steps, or may be impossible to use on systems where Java cannot be installed.

So the trade is real: pdftools is portable and gives you the raw page, tabulizer gives you the table and needs Java. Which one you want depends on whether your environment can run Java, not on which tool is better.

Scanned documents need OCR, and the maintenance picture

The other limitation is scanned text. If you want to extract text from scanned pages in a PDF, you need OCR, and the documentation points at the rOpenSci tesseract package, which provides bindings to the Tesseract OCR engine, and specifically at the section of its vignette about reading from PDF files using pdftools and tesseract together.

So the intended chain for a scanned document is pdftools to render the page to a bitmap, and tesseract to read the bitmap. Neither package does the other's half.

On maintenance, the picture is mixed. The project status badge says active, that the project has reached a stable, usable state and is being actively developed, and the last push was on 2026-08-30. The released versions are v3.2.1 from 2022-10-04, v3.2.0 from 2022-04-19 and v3.1.0 from 2022-02-16.

So the branch has moved considerably since the last CRAN release, which is normal for an R package whose releases come through CRAN review rather than straight from the branch, but it does mean the version you get from install.packages is not the code on master. The documentation is at docs.ropensci.org/pdftools, and the licence is a custom one that the platform cannot classify, with a LICENSE and a LICENSE.md in the repository.

Editorial conclusion

Adopt pdftools if you work in R and need to pull text, metadata or page images out of PDF files without shelling out to a command line tool. Do not expect it to extract tables, because the documentation is explicit that a PDF has no notion of a table and that extracting tabular data is a separate problem. Before you install, check two things: that your platform can get the poppler development library, since Linux needs the Debian, Ubuntu, Fedora or MacOS package, and whether the version you pull still matches your R and poppler combination, because the newest tagged release is v3.2.1 from 2022-10-04 while the last push was on 2026-08-30.

Frequently asked questions

How do I install pdftools in R?

Run install.packages("pdftools"). On Windows and Mac the binary packages come straight from CRAN, while Linux needs the poppler development library: libpoppler-cpp-dev on Debian or Ubuntu, poppler-cpp-devel on Fedora, and brew install poppler on MacOS when building from source.

What does pdf_text return?

A character vector whose length equals the number of pages in the PDF, with each string holding the plain text of that page. Keeping the page boundary in the data is what lets you index and cite by page.

How is pdftools different from the Rpoppler package?

Both wrap poppler, but Rpoppler depends on glib, which does not work well on Mac and Windows. pdftools uses the poppler C++ interface together with Rcpp, which the documentation says results in a lighter and more portable implementation.

Can pdftools extract tables from a PDF?

Not directly. The PDF format has no notion of a table, so tabular data is just positioned lines and text, and it is difficult to extract with pdftools. The dedicated alternative is the tabulizer package, which has interactive selection tools but depends on rJava and needs Java installed.

How do I read a scanned PDF with pdftools?

pdftools has no OCR of its own. Render the page to a bitmap with pdf_render_page and pass it to the rOpenSci tesseract package, which wraps the Tesseract engine, following the section of the tesseract vignette about reading from PDF files using pdftools and tesseract.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. ropensci/pdftools on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ropensci-pdftools.svg)](https://hysenlabs.com/projects/ropensci-pdftools)

Was this useful?