Library / SDK
robjhyndman/forecast avatar
robjhyndman/forecast

forecast: the R package for univariate time series, and where fable takes over

Forecasting Functions for Time Series and Linear Models

1,186 stars337 forksRLicense varies

At a glance

What is it?
The forecast package provides methods and tools for displaying and analysing univariate time series forecasts, including exponential smoothing via state space models and automatic ARIMA modelling, and it is the package behind much of the forecasting taught in R. Its own README points at the fable package as the complementary, tidyverse-native implementation of many of the same models, and that recommendation matters for a new project.
Who is it for?
forecast suits an R user who needs a univariate forecast in a few lines, particularly in a script or a Shiny app where the pipe-friendly model-plus-forecast-plus-autoplot chain is exactly the shape of the answer you want.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly R, according to GitHub's language statistics.

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

Editorial analysis

Univariate, state space, and the pipe that does the work

The R package forecast provides methods and tools for displaying and analysing univariate time series forecasts including exponential smoothing via state space models and automatic ARIMA modelling.

The API is the reason the package has lasted. Every model is a function that takes a time series and returns a model object, and every model object has a forecast method.

r
library(forecast)
library(ggplot2)

# ETS forecasts
USAccDeaths |>
  ets() |>
  forecast() |>
  autoplot()

That chain says: take the series, fit an ETS model, extend it into a forecast, plot it. Three pipes, no configuration, and the result is a plot. The same shape works for automatic ARIMA.

r
WWWusage |>
  auto.arima() |>
  forecast(h = 20) |>
  autoplot()

ets() and auto.arima() are the two automatic model selectors, and they are the entry points most people use. The other entry points are for specific structures. stlm() fits a model with STL decomposition, with the model for the seasonal component given as a function, and stlf() does the same with a frequency argument for non-seasonal data. tbats() is the automatic model for complex seasonality, and arfima() handles fractionally integrated series, which the README demonstrates with a series simulated by the fracdiff package.

r
# Forecasting with STL
USAccDeaths |>
  stlm(modelfunction = ar) |>
  forecast(h = 36) |>
  autoplot()

The restriction to univariate series is the boundary of the package. There is no multivariate forecasting here, and a project that needs joint modelling of several series is looking at a different library.

STL, TBATS and ARFIMA cover the awkward seasonalities

The usage examples in the README are grouped by the awkward case each method handles, and reading them together tells you what the library is actually for.

STL, seasonal-trend decomposition using loess, is the seasonal decomposition approach, and it comes in three flavours in the examples. stlm() with a model function for the seasonal part, stlf() with a lambda argument for series where the seasonal period is not obvious, and stl() with a periodic window, which is the right choice for a series whose seasonal pattern is known rather than estimated.

r
AirPassengers |>
  stlf(lambda = 0) |>
  autoplot()

USAccDeaths |>
  stl(s.window = "periodic") |>
  forecast() |>
  autoplot()

The lambda argument is the log transform, and setting it to 0 says do not transform, which is the right choice for series whose variance is already stable.

TBATS is the automatic approach for seasonality that neither ST nor ARIMA can handle, and the README shows it applied to two different series, USAccDeaths and taylor, which is a monthly airline passengers series and a half-hourly demand series respectively.

r
USAccDeaths |>
  tbats() |>
  forecast() |>
  autoplot()

ARFIMA handles long memory, where the autocorrelation decays more slowly than a standard ARIMA process allows, and the example generates a fractional differencing series with a negative moving average parameter and a fractional differencing order before fitting it.

r
library(fracdiff)
x <- fracdiff.sim(100, ma = -0.4, d = 0.3)$series
arfima(x) |>
  forecast(h = 30) |>
  autoplot()

Taken together, the catalogue covers the three classic reasons a single ETS or ARIMA model fails: unknown seasonality, multiple seasonalities, and long memory. That is a well-considered set of defaults for univariate work.

The README tells you to consider fable first

The second paragraph of the README is the most consequential line in the whole document, and it is easy to skim past.

A complementary forecasting package is the fable package, which implements many of the same models but in a tidyverse framework.

That is the author of forecast saying that a new project should probably not start here. The models are the same, the mathematics is the same, and what differs is the surrounding idiom: tidyverse data frames and verbs against forecast's own object model and base R conventions.

This matters practically in three ways. The first is the pipe idiom, where fable fits into a pipeline that already contains dplyr and tidyr without the awkward type conversions that forecast's objects sometimes require. The second is the growing ecosystem around tidy forecasting, with transformations and plotting helpers written against that world. The third is the direction of travel: a package that recommends a complement rather than trying to absorb it is telling you where the author thinks the work should go.

None of this makes forecast obsolete. It is on CRAN, it is widely installed, and for a script that does one forecast and plots it, the three-pipe chain is shorter than the equivalent in any other framework. The distinction is between a script and a programme.

The topic list is short and unambiguous, just cran, forecast, forecasting and r, and the licence is GPL-3, which the README states directly: this package is free and open source software, licensed under GPL-3.

Installing from CRAN or from GitHub, and the CRAN discipline around it

Installation is the standard R two ways.

r
install.packages("forecast", dependencies = TRUE)

The stable version comes from CRAN, and the dependencies = TRUE argument matters because forecast pulls in a substantial set of compiled and modelling dependencies.

The development version comes from GitHub through pak.

r
# install.packages("pak")
pak::pak("robjhyndman/forecast")

The R-CMD-check badge and the CRAN status badge in the README are the two that matter for anyone depending on this. CRAN check is a demanding gate: it runs the package through a matrix of configurations, checks the documentation against the code, and will not accept a submission with failures. Passing it is a structural guarantee about the package's portability that no badge on a GitHub repository can give you.

The repository layout is a conventional R package. There is R/ for the code, src/ for compiled code, man/ for the Rd documentation, inst/ for installed artefacts, vignettes/ for the long-form articles, tests/ for the test suite, doc/ and data/ for supporting material, and a _pkgdown.yml with a pkgdown/ directory for the website. The pkgdown site is the reference manual, and the package homepage is at pkg.robjhyndman.com/forecast.

There is a NEWS.md at the root, which in an R package is the user-facing changelog and the first file to read before upgrading across a major version.

There is also a .Rbuildignore, which lists the files that should not be shipped in the CRAN tarball, and a cran-comments.md, which records the results of the checks run before submission. The presence of both is a marker of a package that takes the CRAN submission process seriously.

A Makefile that covers the whole R package lifecycle

The Makefile in the repository root is a wrapper around devtools, and its target list is a useful checklist for how the package is maintained.

makefile
default: build

build:
	Rscript -e "devtools::build(args = c('--compact-vignettes=both'))"

check:
	Rscript -e "try(devtools::check('.'), silent=FALSE)"

test:
	Rscript -e "devtools::test('.')"

docs:
	Rscript -e "devtools::document()"

The targets are build, check, clean, coverage, docs, install, pkgdown, revdep, release and test, and the header comment notes that the Makefile is for generating R packages and assumes it is in the top folder of the package.

The revdep target is the one that catches most people out. revdepcheck::revdep_check(num_workers=3) runs a reverse dependency check, which means it installs your new version and then installs and tests every package on CRAN that depends on yours. For a package like forecast, which many other packages depend on, that is the check that tells you whether a change is going to break the ecosystem.

The release target calls devtools::submit_cran with the same compact-vignettes argument as the build, and pkgdown builds the documentation website. The clean target removes the man/*.Rd files, the NAMESPACE, the R history and the Rproj files, which are all generated artefacts.

The pkgdown config file is named with a leading underscore, _pkgdown.yml, which is the convention that stops pkgdown from treating the site config as package content. The air.toml file at the root configures the Air formatter for R, which has become the common choice alongside the original styler.

The result is a package with a documented, repeatable release process, which is the practical answer to whether it is safe to depend on.

Editorial conclusion

forecast suits an R user who needs a univariate forecast in a few lines, particularly in a script or a Shiny app where the pipe-friendly model-plus-forecast-plus-autoplot chain is exactly the shape of the answer you want. It is the wrong choice for a new tidyverse project, because the package itself points at fable as the complementary implementation of many of the same models in a tidyverse framework, and a project built on the older package will carry its conventions with it. Before you adopt it, read that sentence in the README as a decision, and check whether the model you need is one of the automatic ones, because auto.arima and ets pick a specification for you and will occasionally pick one you did not want.

Frequently asked questions

How do I install the R forecast package?

For the stable version, run install.packages("forecast", dependencies = TRUE). For the development version from GitHub, install pak and run pak::pak("robjhyndman/forecast").

What forecasting methods does the forecast package provide?

Exponential smoothing via state space models, automatic ARIMA modelling, STL seasonal decomposition in several forms, TBATS for complex seasonality, and ARFIMA for fractionally integrated series. The README demonstrates each of these.

Should I use forecast or the fable package for a new project?

The README describes fable as a complementary package that implements many of the same models but in a tidyverse framework. For an existing forecast-based script the package is still the shortest path, but a new tidyverse project is pointed at fable by the author.

Can forecast handle multivariate time series?

The package is described as providing methods and tools for displaying and analysing univariate time series forecasts, so multivariate forecasting is outside its scope.

What licence is the forecast R package under?

GPL-3. The README states that this package is free and open source software, licensed under GPL-3, and the package is published on CRAN with a passing R-CMD-check status.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. robjhyndman/forecast 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/robjhyndman-forecast.svg)](https://hysenlabs.com/projects/robjhyndman-forecast)

Was this useful?