Nixtlaverse Documentation Audit
The Nixtlaverse docs are a Mintlify-hosted umbrella over seven open-source forecasting libraries, and the seams show: the landing page miscounts its own libraries, the NeuralForecast intro lists 13 models while the reference table lists 27, a flagship "Models" table renders with zero rows, the canonical TimeGPT quickstart 404s, and install instructions diverge library-to-library — including a documented nightly command that pulls executable wheels over plain HTTP with TLS verification disabled. For a doc set whose own llms.txt invites agents to index it, these are exactly the contradictions that pass a human and silently break a machine.
1. "Five main libraries" but the page renders seven (significant)
Location: https://nixtlaverse.nixtla.io/ (Nixtlaverse landing page)
Problem: The intro states the ecosystem "is primarily built around five main libraries," then immediately renders cards for seven open-source libraries — StatsForecast, MLForecast, NeuralForecast, HierarchicalForecast, DatasetsForecast, UtilsForecast, and CoreForecast — plus two non-OSS products (Nixtla AI, TimeGPT). The prose number and the rendered content disagree on the very first page.
Consequence: The landing page is the canonical entry point and the first thing an indexing agent or new user reads. A reader trying to learn "the five core libraries" has no way to know which five are meant, and an agent extracting "primary libraries = 5" will mis-model the ecosystem. It also reads as unmaintained on page one, undermining trust in everything downstream.
The fix: Make the number match the cards. Either update the prose to "seven open-source libraries" (the actual count rendered), or explicitly name and tier the core five vs. the supporting utilities (UtilsForecast/CoreForecast/DatasetsForecast are arguably support libraries) so prose and content agree.
2. NeuralForecast model count contradicts itself: 13 in the intro vs. 27 in the reference (significant)
Location: https://nixtlaverse.nixtla.io/neuralforecast/docs/getting-started/introduction.html vs https://nixtlaverse.nixtla.io/neuralforecast/docs/capabilities/overview.html
Problem: The introduction's "Model Collection" bullet lists 13 models — "MLP, LSTM, RNN, TCN, DilatedRNN, NBEATS, NHITS, Informer, TFT, PatchTST, VanillaTransformer, StemGNN and HINT." The capabilities/overview page — the authoritative table — lists 27 model rows (Autoformer, BiTCN, DeepAR, DeepNPTS, DilatedRNN, FEDformer, GRU, HINT, Informer, iTransformer, KAN, LSTM, MLP, NBEATS, NHITS, PatchTST, RMoK, StemGNN, TFT, TiDE, TimeMixer, TimeLLM, TimesNet, TimeXer, TSMixer, VanillaTransformer, xLSTM). The intro omits more than half the catalog — DeepAR, TimesNet, iTransformer, KAN, TiDE, TSMixer, TimeMixer, TimeXer, xLSTM, TimeLLM, RMoK, BiTCN, FEDformer, Autoformer, and more.
Consequence: Most users start at the introduction and never reach the overview. A developer evaluating NeuralForecast against a competitor will conclude it lacks DeepAR, TiDE, or any transformer beyond Informer/PatchTST — and may pick another library. An agent answering "does NeuralForecast support TimesNet?" from the intro page will answer "no," which is wrong. Every model the intro does name exists, so this is a completeness/freshness defect rather than a correctness failure — but it is the first list a new user reads.
The fix: Replace the hardcoded 13-model list in the intro with a generated/short pointer ("27 models — see the full collection") that links directly to the overview table, and treat the overview table as the single source of truth so the list can't drift again.
3. StatsForecast "Models" tables render with zero rows (critical)
Location: https://nixtlaverse.nixtla.io/statsforecast/index.html
Problem: Under "Models," the Baseline Models and Exponential Smoothing sections render their full descriptions and complete column headers (Model | Point Forecast | Probabilistic Forecast | Insample fitted values | Probabilistic fitted values | Exogenous features) but contain zero model rows. The "Sparse or Inttermitent" section below them is populated (ADIDA, CrostonClassic), proving the page can render rows — these two families simply don't. (That section header also misspells "Intermittent" as "Inttermitent" — see finding 14.)
Consequence: Two documented, named model families list no models at all. A user looking for which exponential smoothing or baseline models exist (e.g., HistoricAverage, Naive, SeasonalNaive, AutoETS, HoltWinters) finds an empty table and may conclude they aren't supported. For agents, the table parses to an empty capability set for those families.
The fix: Repopulate the Baseline and Exponential Smoothing tables with their model rows and feature checkmarks, and add a render/CI check that fails the build when a model table renders a header with no body rows.
4. NeuralForecast core docstring names the wrong class and mislabels output as "insample" (critical)
Location: https://nixtlaverse.nixtla.io/neuralforecast/core.html
Problem: The NeuralForecast class description reads: "The core.StatsForecast class allows you to efficiently fit multiple NeuralForecast models for large sets of time series." It references core.StatsForecast — a different library's class — inside the NeuralForecast reference. Separately, predict() documents its return (quoted verbatim) as a "DataFrame with insample models columns for point predictions," but predict() returns out-of-sample forecasts, not in-sample fitted values; per the page the same "insample" wording is applied to cross_validation() as well. The predict() signature also exposes h=None documented as "uses the horizon of the fitted models" — meaning the forecast horizon is fixed at model construction, not at predict time.
Consequence: The class-name swap is a copy-paste artifact that confuses anyone reading the authoritative API reference and pollutes any agent that ingests it (it will conflate the two libraries' core classes). The "insample" mislabel is worse: a developer trusting the docstring may believe predict() returns fitted in-sample values and build evaluation logic on that false premise, silently corrupting backtests. The h=None behavior is a quieter trap — a user who passes a horizon to predict() expecting it to take effect won't realize the horizon was bound at model init.
The fix: Change the description to "The core.NeuralForecast class allows you to fit multiple NeuralForecast models," correct the predict() (and, per the page, cross_validation()) return descriptions to say "out-of-sample forecasts" (reserve "insample" for the methods that actually return fitted values), and make the h=None semantics explicit ("horizon is set at model construction; h here only re-slices it").
5. Canonical TimeGPT quickstart URL returns HTTP 404 (critical)
Location: https://nixtlaverse.nixtla.io/nixtla/docs/getting-started/quickstart.html
Problem: This URL — surfaced by web search as the "TimeGPT Quickstart - Nixtla" result — returns a confirmed HTTP 404 (Mintlify error page, Cache-Control: no-store). TimeGPT docs were moved to nixtla.io/docs / docs.nixtla.io, but the old path on this domain is dead with no redirect. The landing page's "TimeGPT" card also points off-domain to https://nixtla.io/docs, and llms.txt lists TimeGPT only under "Optional" pointing off-domain — so the flagship commercial product has no home on this surface, yet a stale-indexed quickstart URL still resolves to a 404 here.
Consequence: A developer following the top Google hit for the TimeGPT quickstart lands on a dead page on the official domain — the single worst first impression for the company's flagship paid product. There's no redirect to the new docs.nixtla.io location, so the user is left to guess.
The fix: Add a 301 redirect from /nixtla/docs/getting-started/quickstart.html (and any other stale /nixtla/... paths) to the current TimeGPT docs at docs.nixtla.io, and submit the updated canonical URLs so search engines reindex.
6. Stale version pin in the StatsForecast install "Warning" (significant)
Location: https://nixtlaverse.nixtla.io/statsforecast/docs/getting-started/installation.html
Problem: The "Warning" callout advises pinning the version and gives a concrete example: pip install statsforecast=="1.0.0". The current released line is 2.x (2.0.3, Oct 2025). The doc's own recommended pin is several major/minor releases stale.
Consequence: Pinning is good advice, but the example is the part people copy. A developer who pastes statsforecast=="1.0.0" installs a years-old release missing models, bug fixes, and API changes — then files issues against behavior that no longer exists. The pinned example actively works against the "avoid issues" intent of the warning.
The fix: Use a current version in the example (e.g., the latest 2.x release), or — better — show the pattern without freezing a literal old version: pip install "statsforecast==2.*" or reference the latest tag, so the example doesn't rot.
7. Nightly-wheel install command runs over plain HTTP with --trusted-host (critical)
Location: https://nixtlaverse.nixtla.io/statsforecast/docs/getting-started/installation.html (Development version)
Problem: The documented nightly install is: pip install --extra-index-url=http://nixtla-packages.s3-website.us-east-2.amazonaws.com --trusted-host nixtla-packages.s3-website.us-east-2.amazonaws.com statsforecast. It uses an http:// index and explicitly passes --trusted-host to disable pip's TLS verification for that host.
Consequence: This is the only true security vulnerability in the doc set: it instructs developers to fetch and install executable Python wheels over an unauthenticated, unencrypted channel, so an on-path attacker can serve a malicious wheel that runs arbitrary code at install time. Copy-pasting this into CI bakes the insecure flag into automated builds, where it executes unattended on every run. It is shipped as the default, documented way to get nightlies.
The fix: Serve the nightly index over HTTPS and drop --trusted-host from the documented command. S3 website endpoints are HTTP-only, so move nightlies behind an HTTPS endpoint (CloudFront/S3 REST endpoint or a proper package index); if HTTP is temporarily unavoidable, add an explicit security warning rather than presenting it as the default install.
8. Install instructions are inconsistent across sibling libraries (significant)
Location: statsforecast/.../installation.html, mlforecast/index.html, hierarchicalforecast/index.html
Problem: Three libraries in the same ecosystem recommend three different install workflows:
- HierarchicalForecast is the only one that recommends
uv: "We recommend usinguvas Python package manager …uv pip install hierarchicalforecast." - StatsForecast recommends pip/conda and pins a version (
statsforecast=="1.0.0"). - MLForecast recommends plain
pip install/conda installwith no pin and nouv.
Consequence: A developer adopting the Nixtlaverse stack (these libraries are explicitly designed to interoperate) gets contradictory tooling advice depending on which page they land on. There's no stated reason HierarchicalForecast needs uv while the others don't, so the inconsistency reads as accident, not intent — and complicates writing one reproducible environment for the whole stack.
The fix: Standardize one recommended install path across all libraries (pip + optional conda + a virtualenv note), and if uv is the house preference, apply it uniformly. Document any genuine per-library requirement explicitly instead of leaving it implied.
9. Inconsistent import path for the same class across pages (minor)
Location: hierarchicalforecast/index.html vs statsforecast/index.html
Problem: The HierarchicalForecast minimal example imports from statsforecast.core import StatsForecast — reaching into the statsforecast.core implementation submodule rather than the package's public top-level (from statsforecast import StatsForecast, the conventional public path the class is exported under). The deeper import is the verbatim, verifiable half; the inconsistency is that the docs teach a submodule path for a symbol that has a public top-level export.
Consequence: Importing from statsforecast.core couples user (and agent) code to an internal module layout. If that internal layout changes, the deeper-path examples break first, and agents that learn the submodule import propagate an unstable convention.
The fix: Standardize on the public top-level import from statsforecast import StatsForecast in every example across the docs, including the HierarchicalForecast minimal example.
10. Reference table footnotes render as digits glued to text, and "mLSTM" family is undefined (minor)
Location: https://nixtlaverse.nixtla.io/neuralforecast/docs/capabilities/overview.html
Problem: The model table's header row renders footnote markers fused into the labels — Model1, AutoModel2, Family3, Univariate / Multivariate4, Forecast Type5, Exogenous6, and cell values like Both8, Any7 — so "Both8" reads as a value rather than "Both" + footnote 8. Separately, the xLSTM row lists its family as mLSTM, a term defined nowhere on the page (the footnotes and other rows never explain it).
Consequence: The glued markers make the most important reference table on the site harder to read and harder for an agent to parse (is the family "Both8" or "Both"?). The undefined mLSTM family value leaves a reader unable to interpret what category xLSTM belongs to.
The fix: Render footnote markers as proper superscripts/links separated from the cell text, and either define mLSTM in the family legend or normalize it to the documented family taxonomy used by the other rows.
11. Trailing/broken inline links and bare-label resources (minor)
Location: statsforecast/index.html and mlforecast/index.html
Problem: Several links render as text with no target. On StatsForecast: "Missing something? Please open an issue or write us in" trails off mid-sentence with no destination, and "Replace FB-Prophet in two lines of code … Check the experiments here." exposes no URL behind "here." On MLForecast, the "Videos → Overview" entry and the "Sample notebooks" links render as bare labels with no visible link targets in the extracted page content.
Consequence: Calls to action that point nowhere are dead weight — a user who wants to "open an issue," see the Prophet benchmark "experiments," or open a sample notebook has no link to follow. The benchmark CTA is especially costly because it backs the headline performance claims (see finding 12).
The fix: Restore the href targets (issue tracker URL, experiments/benchmark repo, video and notebook links). Add a link-check (e.g., a CI crawler) that flags rendered anchor text with empty or missing targets.
12. Headline speed benchmarks are unsourced and undated (minor)
Location: https://nixtlaverse.nixtla.io/statsforecast/index.html (Highlights)
Problem: The Highlights list hard performance multipliers — "500x faster than Prophet," "20x faster than pmdarima," "4x faster than statsmodels," "1,000,000 series in 30 min with ray" — with no library versions, hardware, dataset, or date, and the supporting "Check the experiments here" link has no target (see finding 11).
Consequence: Specific, large multipliers with no reproducible basis read as marketing rather than measurement, and a developer can't verify or reproduce them. Benchmarks also silently age — "500x faster than Prophet" against an unspecified Prophet version may no longer hold, but a reader can't tell.
The fix: Link each claim to a dated, reproducible benchmark (versions, hardware, dataset, script) or move the numbers behind a "Benchmarks" page that states methodology. At minimum, restore the experiments link.
13. llms.txt mixes .md/.html.md mirror paths and excludes the flagship product (minor)
Location: https://nixtlaverse.nixtla.io/llms.txt
Problem: The agent index lists pages via Markdown-mirror URLs that mix two path schemes — some end .md (e.g., coreforecast/index.md), others .html.md (e.g., datasetsforecast/long_horizon2.html.md, utilsforecast/preprocessing.html.md) — neither matching the .html paths the site nav actually serves. The only entry under ## Optional is TimeGPT, pointing off-domain to https://nixtla.io/docs, so the flagship commercial product is not part of the indexed surface at all.
Consequence: llms.txt exists specifically so agents can index the docs, but the inconsistent .md vs .html.md scheme makes it fragile to dead-link drift, and an agent following it will never discover TimeGPT content on this domain. Combined with finding 5 (the stale TimeGPT quickstart 404), TimeGPT is simultaneously dead-linked from search and absent from the machine index.
The fix: Normalize the mirror-path scheme in llms.txt (pick one convention and verify each resolves), and either include the canonical TimeGPT docs URL clearly or document in the index that TimeGPT lives at docs.nixtla.io so agents can route to it.
14. Typos in shipped section headers and nav: "Inttermitent" and "Vist" (minor)
Location: statsforecast/index.html ("Sparse or Inttermitent" section header) and the StatsForecast docs index page that links to the installation page ("Vist")
Problem: Two misspellings appear in rendered, non-prose UI: the StatsForecast model section header reads "Sparse or Inttermitent" (should be "Intermittent"), and the index page linking to the installation docs renders "Vist" (should be "Visit").
Consequence: Typos in section headings and navigation labels — not body prose — read as unreviewed, and "Inttermitent" in particular is a heading an agent or in-page search may key on, so a search for "intermittent" models can miss the section entirely.
The fix: Correct both strings and add a spell-check pass over headings and nav labels (not just paragraph text) to the docs build.
What they do well
- Ships a discoverable
/llms.txtindex and per-page.mdmirrors withLink: rel="llms-txt"headers — the docs are built with agent consumption in mind, which is ahead of most peers. - The NeuralForecast capabilities/overview table is genuinely strong reference material: per-model family, univariate/multivariate, forecast type, and exogenous support in one parseable grid.
- Consistent, familiar
sklearn-style.fit/.predictframing across StatsForecast, MLForecast, and NeuralForecast gives the ecosystem a coherent mental model.
Top 3 recommendations
- Fix the count contradictions and empty tables — reconcile "five libraries" with the seven rendered, make NeuralForecast's intro list defer to the 27-model overview, and repopulate StatsForecast's empty Baseline/Exponential Smoothing tables; add a build check that fails on header-only tables.
- Harden the install docs — drop the plain-HTTP nightly index and
--trusted-hostin favor of an HTTPS endpoint (the one real security exposure), standardize one install workflow across all libraries, and replace the rotting==1.0.0pin example. - Repair the TimeGPT path — 301-redirect the dead
/nixtla/.../quickstart.htmltodocs.nixtla.ioand make TimeGPT's location explicit inllms.txtso neither humans nor agents hit a 404 or a gap.