Skip to content

fastlowess

High-performance LOWESS smoothing for Node.js

npm CI

One LOWESS to Rule Them All
One LOWESS to Rule Them All

The fastest, most robust, and most feature-complete language-agnostic LOWESS (Locally Weighted Scatterplot Smoothing) implementation for Rust, Python, R, Julia, Node.js, C++, Go, Java, and WebAssembly.

The lowess-project also offers bindings for Rust, Python, R, Julia, Node.js, WebAssembly, C++, Go, and Java — see the full repository.


Currently available for R, Python, Rust, Julia, Node.js, WebAssembly, and C++. See the Installation Guide for detailed installation instructions.

GPU acceleration (wgpu: Vulkan, Metal, DirectX 12, and GLES on Android) is also supported for high-throughput batch smoothing. See the GPU Backend guide for details.


FeatureLOESSLOWESS (This Crate)
Polynomial DegreeLinear, Quadratic, Cubic, QuarticLinear (Degree 1)
DimensionsMultivariate (n-D support)Univariate (1-D only)
FlexibilityHigh (Distance metrics)Standard
ComplexityHigher (Matrix inversion)Lower (Weighted average/slope)

Read more about how LOWESS works in the Concepts.

Note: For a LOESS implementation, use loess-project.


It is on average 200-327x faster than Python’s statsmodels.lowess and up to 7.8× faster than base R’s stats::lowess on a tested large, wide-window workload. GPU fastLowess first beats CPU-parallel execution at 25K–50K points, depending on smoothing fraction, and reaches 4.7× speedup over parallel fastLowess CPU execution at 1M points in the tested workload. Small workloads can favor CPU because of GPU overhead; results vary by workload and hardware. See the Benchmarks page for details.

For more details on the performance comparison, see the Benchmarks page.

This implementation is more robust than R’s lowess and Python’s statsmodels due to two key design choices:

MAD-Based Scale Estimation:

For robustness weight calculations, this crate uses Median Absolute Deviation (MAD) for scale estimation:

s = median(|r_i - median(r)|)

In contrast, statsmodels and R’s lowess uses the median of absolute residuals (MAR):

s = median(|r_i|)
  • MAD is a breakdown-point-optimal estimator—it remains valid even when up to 50% of data are outliers.
  • The median-centering step removes asymmetric bias from residual distributions.
  • MAD provides consistent outlier detection regardless of whether residuals are centered around zero.

Boundary Padding:

This crate applies a range of different boundary policies at dataset edges:

  • Extend: Repeats edge values to maintain local neighborhood size.
  • Reflect: Mirrors data symmetrically around boundaries.
  • Zero: Pads with zeros (useful for signal processing).
  • NoBoundary: Original Cleveland behavior

statsmodels and R’s lowess do not apply boundary padding, which can lead to:

  • Biased estimates near boundaries due to asymmetric local neighborhoods.
  • Increased variance at the edges of the smoothed curve.

A variety of features, supporting a range of use cases:

FeatureThis packagestatsmodelsR (stats)
Kernel7 optionsonly Tricubeonly Tricube
Robustness Weighting3 optionsonly Huberonly Huber
Scale Estimation2 optionsonly MARonly MAR
Boundary Padding4 optionsno paddingno padding
Zero Weight Fallback3 optionsnono
Auto Convergenceyesnono
Online Modeyesnono
Streaming Modeyesnono
Confidence Intervalsyesnono
Prediction Intervalsyesnono
Cross-Validation2 optionsnono
Parallel Executionyesnono
GPU Accelerationyesnono
no-std Supportyesnono

All implementations are numerical twins of R’s lowess:

AspectStatusDetails
Accuracy✅ EXACT MATCHMax diff < 1e-12 across all scenarios
Consistency✅ PERFECTMultiple scenarios pass with strict tolerance
Robustness✅ VERIFIEDRobust smoothing matches R exactly

Contributions are welcome! Please see CONTRIBUTING.md for more information.

Licensed under MIT or Apache-2.0.

If you use this software in your research, please cite it using the CITATION.cff file or the BibTeX entry below:

@software{lowess_project,
author = {Valizadeh, Amir},
title = {LOWESS Project: High-Performance Locally Weighted Scatterplot Smoothing},
year = {2026},
url = {https://github.com/thisisamirv/lowess-project},
license = {MIT OR Apache-2.0}
}