# nflfastR turned NFL play-by-play scraping into an R package with models attached

> nflfastR is an R package that scrapes NFL play-by-play data back to 1999 and adds Expected Points, Win Probability, Completion Probability and Expected Yards After the Catch models. The README itself points you at a nightly-updated release archive and the nflreadr package for bulk data access, which is the honest way to use it.

**nflverse/nflfastR** — A Set of Functions to Efficiently Scrape NFL Play by Play Data

- Repository: https://github.com/nflverse/nflfastR
- Website: https://www.nflfastr.com/
- Stars: 551 · Forks: 72
- Language: R
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/nflverse-nflfastr

## What the package actually delivers

The package description is a set of functions to efficiently scrape NFL play-by-play data, and it expands on the earlier nflscrapR project, which the README credits by name to Maksim Horowitz, Ronald Yurko and Samuel Ventura. The feature list is where the value sits. Play-by-play goes back to 1999, and the package obtains games much faster, which is what the name promises and the reason the original project was replaced. On top of the raw data sit several derived measures: completion probability as `cp`, completion percentage over expected as `cpoe`, and expected yards after the catch as `xyac_epa` and `xyac_mean_yardage`, with the play-by-play including those back to 2006. There is also drive information, including drive starting position and drive result, and series information, including series number and series success. A function `update_db()` creates and updates a database, which is the piece that turns one-off scraping into a local research asset.

## The four models and where they come from

nflfastR ships its own models for Expected Points, Win Probability, Completion Probability and Expected Yards After the Catch. The README points to a post on Open Source Football for the model descriptions and recommends a paper from the nflscrapR team on arXiv for the motivation behind Expected Points models in particular. Two structural details are worth knowing before you use them. First, the win probability side is not a single model: the package includes two win probability models, one with and one without incorporating the pre-game spread, so you can choose whether the market's implied prior belongs in the calculation. Second, the model's provenance is partly inherited rather than original. The README credits Nick Shoemaker for finding and making available JSON-formatted NFL play-by-play back to 1999, notes that nflfastR uses this source for 1999 and 2000 and previously also used it for 2001 to 2010, and credits Lau Sze Yui for a scraping function covering 2001 onwards. Charts for scrambles in the 1999 to 2005 seasons come from charting data provided by Aaron Schatz and FTN Fantasy, and Lee Sharpe curated a resource for game information.

## Installing from CRAN, GitHub or the dev universe

The stable install is a single line from CRAN.

```r
install.packages("nflfastR")
```

For a bug fix or a development feature, the README gives two alternatives. The first uses pak to pull straight from GitHub.

```r
if (!require("pak")) install.packages("pak")
pak::pak("nflverse/nflfastR")
```

The second installs a prebuilt binary from the development repo, with the standard CRAN repository kept as a fallback so that other dependencies still resolve.

```r
install.packages("nflfastR", repos = c("https://nflverse.r-universe.dev", getOption("repos")))
```

That r-universe endpoint is worth remembering, because it is the difference between a source build and a prebuilt one for every user on the team, and the README describes it as prebuilt from the development repo. The repository carries a CRAN status badge, a dev version badge pointing at nflfastr.com, an R CMD check workflow badge and a lifecycle badge marked stable, plus a link to a Discord server for support.

## The README tells you not to use the scraper for bulk work

This is the most useful paragraph in the documentation and it is easy to skim past. Even though nflfastR is very fast, the README recommends downloading the data from the nflverse-data releases page or using the nflreadr package instead. Those data sets include play-by-play for complete seasons going back to 1999, they are updated nightly during the season, and the files contain both regular season and postseason data, with game_type or week used to work out which games were postseason. So the package hosts a release of play-by-play data going back to 1999 for quick access, and the scraping functions are the fallback for when the release archive does not yet have what you need, typically the current in-progress week. Using the archive as the default and the scraper as the exception is the pattern the documentation points at.

## Finding the columns and the learning path

Three pieces of documentation are named. The Getting Started article provides application examples, but the README says those require a basic knowledge of R, which is why it recommends the beginner's guide to anyone looking for an introduction to the package. For the data itself, the Field Descriptions article gives column names and descriptions, and the same information is available inside the package as the `field_descriptions` dataframe, so a script can look it up rather than a human copying a table. That is a small but real design point for a package whose value depends on a couple of hundred columns being interpreted correctly. The repository layout backs the same idea: R for the source, man for the documentation, data and data-raw for the datasets and their generation scripts, tests, tools, vignettes, a pkgdown directory for the site and an nflfastR.Rproj file. The README is generated from README.Rmd, so the source of the visible documentation is an R Markdown file.

## Where nflfastR is the wrong tool

Three limits stand out. The first is the language. The package is an R package, published on CRAN with an R package structure, and the documented examples are R. A team working in Python has no documented path, and while the underlying data is hosted as release archives that could be read from any language, the models and the derived columns would have to be recomputed or ported. The second is the freshness model. The archive is updated nightly during the season, and the scraper exists for the case where you need the newest data, but nothing in the documentation describes how the two are reconciled, so a pipeline that mixes the two sources has to decide for itself which source wins on a given day. The third is licensing. The repository holds both a LICENSE file and a LICENSE.md, and GitHub records the licence identifier as a custom one it cannot classify, so unlike a package with a standard MIT or GPL grant you cannot assume what the terms are until you read them. For anything commercial, that file is the first thing to open.

## Conclusion

Adopt nflfastR if you are doing analysis in R and want play-by-play data with Expected Points and Win Probability already joined in, rather than building those models yourself. Skip it if your work is not in R, and skip it if you need the full season history quickly, because the README itself recommends the nightly release archive or the nflreadr package for that. Before you start, read the LICENSE file rather than assuming a standard R licence, and check the field_descriptions dataframe for the column names you plan to use.

## FAQ

### How do I install nflfastR?

The easiest way is from CRAN with `install.packages("nflfastR")`. For a bug fix or a development feature you can install from GitHub with `pak::pak("nflverse/nflfastR")` after installing pak, or get a prebuilt build from the development repo with `install.packages("nflfastR", repos = c("https://nflverse.r-universe.dev", getOption("repos")))`.

### How far back does nflfastR play-by-play data go?

The package contains play-by-play data back to 1999. The completion probability, completion percentage over expected and expected yards after the catch measures are included going back to 2006.

### Which models does nflfastR include?

Expected Points, Win Probability, Completion Probability and Expected Yards After the Catch. The package includes two win probability models, one with and one without incorporating the pre-game spread.

### Should I scrape data with nflfastR or download it?

The README recommends downloading from the nflverse-data release page or using the nflreadr package, since those play-by-play files cover complete seasons back to 1999 and are updated nightly during the season. It says this even though nflfastR itself is fast.

## Sources

- [Issues](https://github.com/nflverse/nflfastR/issues)
- [nflverse/nflfastR on GitHub](https://github.com/nflverse/nflfastR)
- [Project website](https://www.nflfastr.com/)
- [README](https://github.com/nflverse/nflfastR/blob/master/README.md)
- [Releases](https://github.com/nflverse/nflfastR/releases)

---

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