Self-hosted service
unit8co/darts avatar
unit8co/darts

Darts: One fit/predict interface across ARIMA, neural nets and anomaly scorers

A python library for user-friendly forecasting and anomaly detection on time series.

9,521 stars1,043 forksPythonApache-2.0

At a glance

What is it?
Darts is a Python library that wraps classical and deep learning time series models behind a scikit-learn-like API, and adds an anomaly detection layer on top. The judgement: the uniform interface is the real product, and the cost is a heavyweight dependency tree.
Who is it for?
Adopt Darts if you need to move between ARIMA-style baselines and neural forecasters without rewriting your pipeline, and you accept a Python 3.10+ environment with a large dependency set. Do not adopt it if you want a small, torch-only training loop you fully control, or if your data is irregular event streams rather than a regularly indexed series.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

The problem Darts solves is API churn, not missing algorithms

Time series work in Python has a fragmentation problem. ARIMA lives in statsmodels, exponential smoothing in statsmodels, gradient boosted trees in LightGBM or XGBoost, neural forecasters in PyTorch or TensorFlow, and anomaly detection in PyOD. Each has its own input format, its own notion of a time index, its own way of producing a prediction interval. Moving from a baseline to something more expressive usually means rewriting the data plumbing, not the model.

Darts targets that specific cost. The README states that its forecasting models can all be used the same way, through fit() and predict() functions, similar to scikit-learn. The audience is therefore engineers and data scientists who want to compare several model families on one dataset without maintaining several adapters. It is not aimed at someone who needs one specific algorithm and wants the thinnest possible wrapper around it.

The second problem is anomaly detection. The README describes it as trivial to apply PyOD models on time series to obtain anomaly scores, or to wrap any Darts forecasting or filtering model to obtain a full anomaly detection model. That is a narrower claim than it sounds: the value is the reuse of the same TimeSeries container and the same fit/predict rhythm, so a forecasting model you already trust becomes a residual-based detector.

TimeSeries is the load-bearing abstraction

Everything in Darts passes through the TimeSeries object. The README example reads a CSV with pandas, then constructs one with TimeSeries.from_dataframe(df, "Month", "#Passengers"), naming the time column and the value column explicitly. That object is what models consume and what they return.

Slicing is how you split. The same example writes train, val = series[:-36], series[-36:], and the anomaly example uses series.split_before(0.6). Both produce TimeSeries instances rather than arrays, which is why the model call sites stay short. The cost is that your data has to be expressible as a regularly indexed series with a defined frequency, since the whole design assumes a time axis that models can step forward along. Irregular event data does not fit this container without you resampling it first, and resampling is a modelling decision, not a formatting one.

Multivariate support is stated directly: Darts supports both univariate and multivariate time series and models. The anomaly walkthrough loads ETTh2Dataset, trims it to the first 10000 points, selects two components by name (["MUFL", "LULL"]), and splits. Component selection by column name is part of the same abstraction, which matters because a scorer that expects one column and receives two will fail at fit time rather than silently.

The documentation also states that ML-based models can be trained on potentially large datasets containing multiple time series. That is a different shape from a single long series, and it is where the library's transfer learning and multi-series training material sits.

Forecasting and anomaly detection share one workflow

The forecasting path is short. Construct an ExponentialSmoothing model, call model.fit(train), then model.predict(len(val), num_samples=1000). The num_samples argument is what makes the output probabilistic rather than a single line: the README then plots the median with 5th and 95th percentiles via prediction.plot(label="forecast", low_quantile=0.05, high_quantile=0.95). Not every model supports that argument, and the README only claims rich probabilistic support for some of the models, so the sampling interface is not a uniform guarantee across the catalogue.

The anomaly path is deliberately split into two stages. A scorer produces continuous anomaly scores; a detector turns those scores into binary flags. The README builds a KMeansScorer(k=2, window=5), fits it on train, and scores the validation set. Then a QuantileDetector(high_quantile=0.99) is fitted on the training scores, not on the raw series, and applied to the validation scores to produce binary_anom.

That two-stage design is the most interesting structural choice in the library. It means the threshold is learned from a distribution of scores rather than chosen by hand, and it means you can swap the scorer while keeping the detector, or vice versa. It also means a detector fitted on training scores inherits whatever bias the scorer has on that period. If the training window contains an anomaly that the scorer flags, the 0.99 quantile absorbs it and the detector becomes less sensitive downstream.

Installation and the extras problem

The README recommends setting up a clean Python environment with Python 3.10+ using conda, venv, or virtualenv, then running:

pip install darts

It points to INSTALL.md for more detail, and the badges indicate a conda-forge package published as u8darts-all and a Docker image at unit8/darts. The existence of a separate INSTALL.md and an all-inclusive conda package is itself a signal: the base pip install and the full set of model backends are not the same thing. The README does not enumerate which models require which optional dependencies, so the only way to know whether your intended model works after pip install darts is to try importing it.

This is the main practical friction point. A library that spans ARIMA, exponential smoothing, gradient boosting, and deep neural networks necessarily pulls from several ecosystems, and the deep models in particular imply a framework dependency. The README does not state which deep learning backend is used or whether it is optional in the base install. Anyone planning to use only the classical models should check whether the install they get is heavier than they want.

Licence is Apache-2.0, which permits commercial use and modification with the usual notice and patent-grant terms. That is a permissive licence, but it says nothing about the licences of the optional backends you pull in, and those are your responsibility to check.

Where Darts is the wrong tool

The TimeSeries container is the constraint. If your timestamps are irregular, if your series has gaps that are meaningful rather than missing, or if you are working with event logs rather than measurements on a grid, you will spend more effort bending the data into shape than modelling it. A pandas DataFrame plus a model that accepts a plain array is a shorter path in that case.

The second boundary is control. The uniform fit/predict interface is achieved by hiding backend-specific behaviour. If you need custom training loops, custom loss functions, or access to intermediate tensors, the abstraction works against you. The README describes the interface as similar to scikit-learn, and that similarity is exactly the layer you would be fighting.

The third boundary is the anomaly detection claim. The README says it is trivial to apply PyOD models on time series, but the demonstrated path is a two-stage scorer-then-detector pipeline whose second stage is fitted on training scores. On a short training window, a 0.99 quantile is estimated from very few effective observations, and the detector's behaviour near that boundary is not something the README characterises. Treat the detector threshold as a parameter you must validate on held-out data, not as a default you can trust.

Finally, the release cadence visible in the metadata is rapid: three releases between mid-July and early September 2026, including two minor versions. Frequent minor releases mean the API you pin today may shift, and pinning a version is the reasonable default for anything in production.

Alternatives and the actual difference in approach

The closest comparison in scope is sktime, which also unifies forecasting under a scikit-learn-style interface. The difference is where the abstraction sits. sktime is built around the estimator interface itself, with a wide set of adapters to other libraries, and it is oriented toward composing and benchmarking estimators. Darts is built around the TimeSeries container and a curated model catalogue, with the anomaly detection layer as a first-class sibling to forecasting. If you want to plug in an arbitrary third-party estimator, sktime's adapter model is the more natural fit. If you want one container that carries your series through forecasting and anomaly scoring with the same slicing semantics, Darts is the more direct route.

For pure deep learning forecasting, the PyTorch Forecasting library is the other obvious reference point. It is tied to PyTorch and Lightning, and its data structure is a dataset object designed for training neural networks on many series. That gives you closer access to the training loop and the Lightning ecosystem, at the cost of the classical model families. Darts keeps ARIMA and exponential smoothing in the same namespace as the neural models, which is the whole point.

For anomaly detection specifically, PyOD alone is a legitimate choice, and the README treats it as a component rather than a competitor. The difference is that PyOD operates on arrays and expects you to handle the temporal structure yourself. Darts' contribution is the windowing and the scorer/detector split, not a new anomaly algorithm.

Maintenance cost and what to verify before adopting

The upgrade surface is the dependency tree, not the Darts API. Because the library spans several model families, a new minor release can move a pinned backend version, and the release history shows minor versions arriving roughly two months apart. The practical posture is to pin darts in your requirements file, run your own backtest after each bump, and read the release notes rather than assuming a patch release is inert.

The Apache-2.0 licence imposes no copyleft obligation on your code, so embedding Darts in a commercial product is permitted under that licence. It does not resolve the licensing of optional backends, and it does not cover the datasets bundled in darts.datasets, which carry their own provenance. If you use ETTh2Dataset or similar in anything shipped, check the original dataset terms separately.

What to verify first, concretely: create the clean Python 3.10+ environment the README asks for, run pip install darts, and then import the specific model classes you intend to use. The README's own examples give you the exact names to test, from darts.models import ExponentialSmoothing and from darts.ad import KMeansScorer, QuantileDetector. If a model you need does not import from the base install, consult INSTALL.md before assuming the library is broken. After that, reproduce the two walkthroughs on your own data, because the AirPassengers and ETTh2 examples are small and clean in a way production series rarely are.

Editorial conclusion

Adopt Darts if you need to move between ARIMA-style baselines and neural forecasters without rewriting your pipeline, and you accept a Python 3.10+ environment with a large dependency set. Do not adopt it if you want a small, torch-only training loop you fully control, or if your data is irregular event streams rather than a regularly indexed series. Before committing, install it in a clean environment and confirm that the models you actually intend to use import and fit on your own data, because the extras and optional backends are where the friction lives.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. unit8co/darts on GitHub
Community notes

Community notes