mlr3: the R machine learning framework rebuilt around R6 objects and a package-per-feature split
mlr3: Machine Learning in R - next generation
At a glance
- What is it?
- mlr3 keeps only the core building blocks of machine learning in one CRAN package and pushes learners, tuning and pipelines into separate extension packages. The design is deliberate and the cost is real: you will install more than one package before anything useful happens.
- Who is it for?
- Adopt mlr3 if you already work in R and want one interface over many learners, resampling schemes and measures, and you accept that a usable setup means installing mlr3verse or several extension packages rather than mlr3 alone. Do not adopt it if you want a single dependency, or if your modelling happens in Python and R is only a plotting layer.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly R, 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 mlr3 solves is interface churn, not missing algorithms
R has no shortage of modelling functions. What it lacks is a common shape for them. A random forest from one package and a gradient boosting model from another take different argument names, return different object types, and expect the data in different containers. Every time you switch models you rewrite the glue around the fit. mlr3 exists to put one interface in front of that scatter. The README frames the package as "efficient, object-oriented programming on the building blocks of machine learning" and describes it as the successor to mlr, which was first released to CRAN in 2013. The rewrite was motivated by what the authors call feature creep in the original: too much in one package, hard to maintain, and hard to extend from the outside. So the audience is R users who compare several learners on the same data and want the comparison code to survive a change of model. It is not aimed at someone who wants to call rpart once and be done.
Tasks, learners and resamplings are separate objects that get passed around
The architecture is visible in the README example. A dataset is first wrapped into a task with as_task_classif(species ~ ., data = palmerpenguins::penguins). The task carries the target, the feature types and the class distribution, and the printed output shows exactly that: 344 rows, 8 columns, target species, properties multiclass, seven features split into int, dbl and fct, and the target class shares. A learner is then constructed independently with lrn("classif.rpart", cp = .01). Nothing about the learner knows the data yet. Training is a method call on the learner that takes the task and a row index vector: learner$train(task_penguins, split$train_set). Prediction is the same pattern, and the result is a prediction object with its own methods, prediction$confusion and prediction$score(measure). Resampling follows the same discipline. rsmp("cv", folds = 3L) builds a resampling object, resample(task, learner, resampling) runs it, and the result is a resample result whose $score() returns a data.table with one row per fold and $aggregate() collapses to a single number. Every stage is an object with a defined role, which is why the same learner can be dropped into a different task or a different resampling without touching the learner code.
Getting it running takes one install line, but a usable setup takes two
The README gives three installation paths. The released version is install.packages("mlr3"). The development version is pak::pak("mlr-org/mlr3") after installing pak. For actual work the README recommends a third: install.packages("mlr3verse"), described as a meta-package that installs mlr3 plus some of the most important extension packages. That recommendation is the honest one. The core package holds the building blocks, so the learner you want is probably not in it. The README points to mlr3learners for recommended core regression, classification and survival learners, and mlr3extralearners for everything else, with a learner search page on the mlr-org site to check what exists. There is also a book at mlr3book.mlr-org.com, which the README calls the central entry point, plus a reference manual, an FAQ and cheatsheets for mlr3, mlr3tuning and mlr3pipelines. For a first run, the example in the README needs palmerpenguins as well as mlr3, since the task is built from palmerpenguins::penguins.
The extension package split is the design, and it is also the friction
Splitting learners, tuning and pipelines into separate packages keeps the core small and lets each piece move on its own release schedule. The cost lands on the user. A workflow that tunes hyperparameters and chains preprocessing steps touches mlr3, mlr3learners, mlr3tuning and mlr3pipelines, and each of those has its own version and its own compatibility window with the core. The README does not describe a version pinning scheme for that combination, and it does not state a support policy for older core releases. What it does offer is mlr3verse as a bundle, which reduces the version-matching problem to one install but does not remove it: the meta-package still resolves against whatever the current CRAN state is. If you need a frozen environment, the repository material does not tell you how to get one, and that is a gap worth knowing about before you commit.
Where mlr3 is the wrong tool
mlr3 assumes you are working in R and intend to stay there. The object model is R6-based and the results are R objects; the resample result prints as a data.table, which is idiomatic R and not much use as an interchange format for a Python service. If your production model is served from Python and R is only where you explore, adopting mlr3 means maintaining a second modelling stack whose outputs you then have to translate. The same applies to one-off fits. For a single rpart call on one dataset, the task-learner-resampling ceremony in the README is more code than the direct call, and the abstraction earns nothing. There is also a maintenance signal in the README's own history: the authors describe the previous generation as suffering from feature creep that made it hard to maintain, and the response was a full rewrite rather than an incremental fix. That is a reasonable decision, but it means the API you learn is the second one this group has shipped, and the README does not commit to API stability guarantees for the core.
What it competes with, and how the approach differs
The direct alternative inside R is caret, which has served the same role for far longer: one train() call, one set of resampling controls, a long list of supported models. The difference is structural rather than a matter of feature lists. caret centres on a single training function with a formula-and-method interface, and the model-specific code lives in internal hooks. mlr3 centres on separate objects for task, learner, resampling and measure, each of which can be constructed, inspected and passed around on its own, and the model-specific code lives in other packages entirely. That split is what makes the README's resample example work without the learner knowing anything about the resampling. It is also what makes the install heavier. The README's own framing of the rewrite supports this reading: mlr was considered nicely extensible in some parts, such as learners and measures, and less easy to extend from the outside in others. mlr3 moves the extensible parts out into packages so that outside extension is the normal path rather than a special case.
Licence and the cost of keeping up
mlr3 is LGPL-3.0. That is a copyleft licence with a linking exception tradition, and it is a different obligation from the MIT or GPL-2 licences common in R packages. If you are embedding mlr3 in a distributed application rather than using it interactively for analysis, the licence terms are something to read rather than assume, and this article is not legal advice. On maintenance: the repository shows releases v1.7.0 and v1.7.1 in June 2026 and v1.8.0 in August 2026, so the core is on a steady cadence and minor releases arrive close together. The upgrade cost is mostly borne by the extension packages, since a core change can require a matching update in mlr3learners, mlr3tuning or mlr3pipelines. The README does not publish a deprecation timeline, so the practical check before upgrading is to run your existing resample code against the new core version and confirm the extension packages you depend on have released against it. The README does list a Mattermost chat and a Stackoverflow tag (mlr3) as support channels, which is where a version mismatch question would go.
Editorial conclusion
Adopt mlr3 if you already work in R and want one interface over many learners, resampling schemes and measures, and you accept that a usable setup means installing mlr3verse or several extension packages rather than mlr3 alone. Do not adopt it if you want a single dependency, or if your modelling happens in Python and R is only a plotting layer. Verify first that the specific learner you need is in mlr3learners or mlr3extralearners rather than in the core package, because the core deliberately ships the building blocks and not the model implementations.
Community notes