fklearn: nubank's functional wrapper for scikit-learn-style ML pipelines
fklearn: Functional Machine Learning
At a glance
- What is it?
- fklearn applies functional programming ideas to machine learning workflows, wrapping model training, validation and production scoring in composable functions. It targets teams that need validated models to match production models, and it carries the operational assumptions of a bank that ships models as services.
- Who is it for?
- Adopt fklearn if your team already thinks in scikit-learn estimators and you need the same transformation code to run in cross-validation and in production scoring, with LightGBM, XGBoost or CatBoost as the learner. Do not adopt it if you need a serving runtime, a feature store, or a scheduler; fklearn supplies none of those, and the README does not claim otherwise.
- 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 97 days ago.
- What is it written in?
- Mainly Jupyter Notebook, 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 fklearn was built to answer
Most machine learning libraries optimise for the experiment. You fit a model in a notebook, you look at a metric, you move on. The gap opens later, when the transformation that produced your training features has to be reproduced exactly at scoring time, in a different process, possibly months after the notebook was last opened. fklearn's stated principles speak directly to that gap. The README lists four: validation should reflect real-life situations, production models should match validated models, models should be production-ready with few extra steps, and reproducibility and in-depth analysis of model results should be easy to achieve. Those are operational goals, not modelling goals, and they explain why the library exists inside Nubank rather than as a general-purpose toolkit. The intended user is an engineer or data scientist who owns a model past the point of validation, who has to hand a scoring function to a service, and who has been burned by a train and serve mismatch. If you only ever run offline analysis and never deploy, the library's central concern is not yours.
How the functional composition actually works
The name is a deliberate reference to scikit-learn, and the README says so. What differs is the unit of composition. Instead of an estimator object that holds fitted state and exposes fit and predict methods, fklearn is organised around functions that take a dataset and return a dataset, with learned parameters carried alongside rather than hidden inside the object. That shape is what makes the same transformation runnable in a cross-validation loop and in a scoring job without rewriting it. The repository is primarily Jupyter Notebook according to the language breakdown, which is consistent with a library whose documentation doubles as executable examples. The README does not include a worked pipeline example in the text shown, so the concrete API surface has to be read from the API docs at fklearn.readthedocs.io rather than from the front page. That is a real friction point for evaluation: you cannot judge the ergonomics of the composition primitives from the README alone, and you should budget time to read the getting started page before deciding.
Model backends and the extras that gate them
fklearn does not ship its own gradient boosting implementation. The install section names four extras that pull in third-party learners: fklearn[lgbm] for LightGBM, fklearn[xgboost] for XGBoost, fklearn[catboost] for CatBoost, and fklearn[all_models] for all three. There is also fklearn[all], described as all models plus tools. A plain pip install fklearn gives you the core without those backends, so the first thing to check against your own stack is which extra you need. The choice matters beyond installation. These three libraries differ in categorical feature handling, in their default regularisation, and in how they serialise trained models, and fklearn's wrapper does not erase those differences. If your team has standardised on one of them, install the matching extra and ignore the others; pulling in all three adds dependency surface without adding capability you will use.
Getting a development environment running
The README documents uv as the dependency manager, and the commands are specific. uv sync creates a virtual environment, installs all locked dependencies, and installs fklearn itself in editable mode, so changes under src/ take effect without reinstalling. uv sync --all-extras additionally installs lgbm, xgboost, catboost, tools, demos and docs. The dev dependency group, which the README lists as pytest, ruff, mypy and hypothesis, is included by default through tool.uv.default-groups, so a bare uv sync is enough for most development workflows. Tests run with uv run pytest --cov=src/. Linting and formatting both go through ruff: uv run ruff check src/ tests/ and uv run ruff format src/ tests/. Dependencies are added with uv add for runtime and uv add --dev for development. There is one contributor-specific note: Nubank contributors are told to regenerate the lockfile with uv lock --default-index https://pypi.org/simple/, which implies the default index in their environment is not public PyPI. If you fork the project, that line will not apply to you.
Where fklearn is the wrong tool
fklearn is a modelling and validation library. It is not a serving framework, not a feature store, and not an orchestrator. Nothing in the README describes an HTTP endpoint, a batch scheduler, a model registry, or drift monitoring, and the four stated principles are about matching validated models to production models, not about running them. If your problem is that features are computed differently across five services, fklearn will not fix it; it will only guarantee that the pipeline you define behaves identically wherever you call it. There is a second limitation that follows from the project's origin. The library is maintained by Nubank and reflects their internal conventions, which is visible in the contributor note about the lockfile index. That does not make it unusable outside the company, and the Apache-2.0 licence places no such restriction, but it does mean feature priorities are set by one organisation's production needs. If your requirements diverge from a consumer credit operation, expect to carry your own patches.
How this differs from plain scikit-learn pipelines
The obvious comparison is scikit-learn's own Pipeline and ColumnTransformer. Both wrap preprocessing and a final estimator into one object you can cross-validate. The difference is in where state lives. A scikit-learn Pipeline holds fitted transformers as attributes after fit, and the object you cross-validate is discarded once you refit on the full dataset. fklearn's functional framing, as described in its principles, keeps learned parameters as values that travel with the data flow, which is what allows the validated pipeline and the production pipeline to be the same artefact rather than two objects that happen to have been configured identically. That distinction is the whole point of principle two. If you have never been bitten by a train and serve skew, the scikit-learn approach is simpler, better documented, and has a far larger user base to draw answers from. fklearn trades that familiarity for a stricter guarantee about parity, and that trade is only worth making if parity is a problem you actually have.
Versioning, licence and what maintenance costs you
Recent releases are frequent and small: 4.2.3, 4.2.2 tagged Workflow Feature, and 4.2.1 described as a version bump following changes from a pull request. That pattern suggests incremental maintenance rather than periodic large rewrites, which is generally cheaper to track. Upgrading across minor versions in a 4.x line is the expected path, and the changelog entries shown give no indication of breaking API changes. The licence is Apache-2.0 per both the README badge and the LICENSE file, which permits commercial use, modification and redistribution provided you preserve notices and state changes. That is a permissive licence and imposes no copyleft obligation on your own code. This is a description of the licence text, not legal advice; if you are embedding fklearn in a distributed product, have your own counsel confirm the notice requirements. The real maintenance cost is not the library, it is the model backends. LightGBM, XGBoost and CatBoost each release on their own schedule, and fklearn's extras pin ranges rather than exact versions, so a backend upgrade can land in your environment without a corresponding fklearn release.
Editorial conclusion
Adopt fklearn if your team already thinks in scikit-learn estimators and you need the same transformation code to run in cross-validation and in production scoring, with LightGBM, XGBoost or CatBoost as the learner. Do not adopt it if you need a serving runtime, a feature store, or a scheduler; fklearn supplies none of those, and the README does not claim otherwise. Before committing, verify three things in the repository: that the model backend you use has an extra under pip install fklearn[all_models], that the licence file at LICENSE matches Apache-2.0 as the README states, and that the pipeline composition primitives you rely on appear in the API docs at fklearn.readthedocs.io, since the README itself shows no end-to-end code example.
Community notes