simple-statistics: descriptive, regression and inference statistics in plain JavaScript
simple statistics for node & browser javascript
At a glance
- What is it?
- A dependency-free JavaScript statistics library that runs in Node, bundlers and the browser. It covers the common descriptive and regression work well, and its documentation is thinner than its API surface.
- Who is it for?
- Adopt simple-statistics when you need descriptive statistics, quantiles, or a least-squares regression line inside JavaScript that already runs in Node or a browser, and you want no runtime dependencies in the bundle. Do not adopt it if you need a DataFrame abstraction, column-wise operations over large tabular data, or streaming aggregation over data that does not fit in memory; the library takes arrays and returns numbers.
- Can I use it commercially?
- Yes. ISC 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 3 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 26, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What simple-statistics is for, and who reaches for it
The README describes the project as "a JavaScript implementation of descriptive, regression, and inference statistics", implemented in literate JavaScript with no dependencies. That single sentence sets the boundary: this is a function library, not a data analysis environment. You bring an array of numbers, you call a function, you get a number or a small object back. There is no table type, no column selection, no query language.
The audience follows from that. A frontend developer who needs a median or a standard deviation for a chart annotation, and does not want to pull a statistics runtime into a page bundle, is the natural user. So is a Node script that computes a regression line over a few hundred rows read from a CSV. The library also fits teaching contexts, because each function is small enough to read. The README points to a separate SEEALSO.md listing other statistics libraries, which is a fair signal that the maintainers see this as one option among several rather than a platform.
The wrong user is anyone who thinks of the problem as data manipulation first. If your first move is to group, join or pivot before you aggregate, you want a dataframe library and should call simple-statistics only for the final numeric step, if at all.
How the code is organized: literate source, bundled output, one entry point
The repository layout shows the mechanism clearly. Source lives in src/, with index.js at the top level acting as the aggregation point for the public API. The package.json declares "source": "index.js", and the build script runs rollup -c rollup.config.mjs to produce the dist/ artifacts. Consumers never touch src/ directly through the package entry point; they resolve through the exports map.
That map is the part worth reading carefully. For the "." entry, package.json lists "types": "./index.d.ts", "import": "./dist/simple-statistics.mjs", and a "browser" condition pointing at the minified UMD build. The main field points at dist/simple-statistics.cjs for CommonJS consumers, and the unpkg field points at dist/simple-statistics.min.js for script-tag use. In other words, one source tree produces four consumption paths: ESM, CJS, UMD for browsers, and a TypeScript declaration file. The type definitions are hand-maintained as index.d.ts rather than generated by the build, which is a maintenance cost the repository accepts.
Data flow inside the library is deliberately flat. A function receives an array, iterates it, and returns a scalar or a small structure. There is no shared internal state and no configuration object threaded through calls. That is what makes the no-dependency claim credible, and it is also why the library cannot offer incremental or streaming computation: nothing in the design holds a running accumulator across calls.
Installing simple-statistics and computing a first regression
The README's installation section branches by environment. For a project that uses a module bundler and installs from npm, the first step is the install command itself. This adds the package and, because the library has no runtime dependencies, nothing else comes with it.
npm install simple-statisticsHow you import it depends on your module system. The README gives both forms. With CommonJS, the require call returns an object carrying every method, and you assign it to whatever name you like. The README's example uses ss.
var ss = require('simple-statistics')With ES modules the README is explicit that the package has "only named exports for ES6". You can import the namespace, or pull in a single function by name.
import * as ss from 'simple-statistics'
import {min} from 'simple-statistics'A first real use is a regression line. The package is built around arrays of numbers and arrays of pairs, so the input shape is the main thing to get right. A linear regression takes an array of [x, y] pairs and returns an object with the slope and intercept of the fitted line. The README does not show this call, so check the API documentation for the exact function name and return shape before wiring it in.
If you are not using a bundler at all and are writing a plain page, the README shows the script-tag route. In that mode the global variable name is not yours to choose: the library always becomes available as ss, and you may reassign it afterward if you want.
<script src='https://unpkg.com/[email protected]/dist/simple-statistics.min.js'>
</script>The README also documents a Deno path, recommending Deno's NPM compatibility and importing the module as npm:simple-statistics. For browsers that support ES modules, it shows an unpkg ?module import from index.js, and labels that route experimental and bleeding-edge. Treat the script-tag and npm paths as the settled ones.
Where simple-statistics stops: array inputs, no streaming, no data frames
The most consequential limitation is the input contract. Functions take arrays, which means the data has to be in memory as a JavaScript array before you can compute anything. For a chart with a few thousand points this is irrelevant. For a log-processing job over millions of rows, it is the deciding factor. The library offers no incremental mean, no running quantile sketch, no way to fold chunks into a previous result. You either materialize the array or you do not use this tool.
A second limitation is that the project is a set of statistical primitives, not a data manipulation layer. There is no groupBy, no column accessor, no handling of missing values beyond whatever the individual function does. If your data arrives as objects with named fields, converting it to the arrays the functions expect is your code, not the library's. That conversion is where most bugs in a first integration actually live, because a silently reordered pair array produces a plausible-looking regression line rather than an error.
Third, the type definitions are a separate file maintained alongside the source. index.d.ts is listed in the published files and the prelint script runs tsc --skipLibCheck --noEmit, so the types are checked in CI. That is reassuring but not a guarantee of parity with the runtime at every release; a function can exist in src/ before it appears in the declarations. If you are writing TypeScript, check the declaration file for the function you intend to use rather than assuming the API docs site and the types agree.
simple-statistics compared with a dataframe-style JavaScript library
The obvious alternative for JavaScript users is a dataframe library in the Danfo.js or Arquero style. The difference is architectural, not a matter of which is better. Those libraries model a table: named columns, typed values, chainable operations like select, filter, groupby and aggregate, and in some cases a columnar memory layout. simple-statistics models a function: a name, an array, a return value.
That has practical consequences. With a dataframe library, computing a grouped mean is one expression and the library handles the grouping. With simple-statistics you group the data yourself, build an array per group, and call the mean function once per group. The second approach is more code but has no abstraction to learn and no runtime to ship. Conversely, the dataframe library can express operations that simple-statistics simply does not have, and it can often avoid materializing intermediate arrays.
There is also a size argument that cuts in simple-statistics' favor for browser work. Because the package has no dependencies and ships a minified UMD build, a page that needs a median and a standard deviation can include one file. A dataframe library carries considerably more machinery. The trade is capability for weight, and the right side of that trade depends on whether your statistics are the whole job or the last step of one. The README links to SEEALSO.md precisely because the maintainers treat this as a choice among libraries rather than a replacement for all of them.
Maintenance, release process and the ISC licence in practice
The repository is not archived, and the last push was on 2026-09-16. Recent releases are close together: v7.12.0 on 2026-09-08, v7.11.0 on 2026-08-29, and v7.10.2 on 2026-08-19. The versioning is handled with Changesets, visible in the .changeset/ directory and the @changesets/cli dev dependency, with a changeset:version script that runs changeset version and then a script to update the README. That last detail matters for upgrade cost: the README's install examples embed a version number, so the README is regenerated as part of the release flow rather than edited by hand.
Upgrade cost for consumers is low in the normal case. The package publishes four entry points and a declaration file, and version bumps within the 7.x line are additive per the changelog conventions implied by Changesets. The risk to watch is the exports map. If a future release changes which file a condition resolves to, a bundler configuration that hardcodes a dist/ path rather than importing the package name will break. Importing "simple-statistics" and letting the resolver pick is the safer pattern.
The licence is ISC, a permissive licence structurally similar to MIT in what it allows. The LICENSE file is included in the published files list, so it ships with the package. This is not legal advice, but the practical implication for most teams is that ISC imposes no obligation beyond retaining the copyright notice and permission text, and it does not carry the patent grant language found in Apache 2.0. If your organization has a policy that requires an explicit patent grant, ISC will not satisfy it and you should route the decision through whoever owns that policy.
Editorial conclusion
Adopt simple-statistics when you need descriptive statistics, quantiles, or a least-squares regression line inside JavaScript that already runs in Node or a browser, and you want no runtime dependencies in the bundle. Do not adopt it if you need a DataFrame abstraction, column-wise operations over large tabular data, or streaming aggregation over data that does not fit in memory; the library takes arrays and returns numbers. Before committing, verify two things in your own environment: that your bundler resolves the exports map to dist/simple-statistics.mjs or dist/simple-statistics.cjs as expected, and that the specific function you need is present in index.d.ts, since the API documentation site and the type definitions are separate artifacts that can drift.
Frequently asked questions
What is simple-statistics?
It is a JavaScript implementation of descriptive, regression and inference statistics, written in literate JavaScript with no dependencies and designed to work in modern browsers as well as Node.js. It exposes functions that take arrays and return numbers or small result objects.
How do I install simple-statistics from npm?
Run npm install simple-statistics, then load it with require('simple-statistics') under CommonJS or with import * as ss from 'simple-statistics' under ES modules. The README notes that the package has only named exports for ES6.
Can I use simple-statistics in a browser without a bundler?
Yes. The README shows a script tag pointing at the minified UMD build on unpkg, and in that mode the library is always exposed globally as the variable ss. It also documents an experimental ES module route through unpkg's ?module parameter, which it labels bleeding-edge.
Does simple-statistics have any runtime dependencies?
The README states that the library is implemented with no dependencies, and the package.json lists only devDependencies used for building, linting, testing and release tooling. Nothing is pulled into your bundle at runtime.
What licence does simple-statistics use?
The repository is licensed under ISC, and the LICENSE file is included in the published files list in package.json. ISC is permissive and does not include the explicit patent grant found in some other licences.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/simple-statistics-simple-statistics)
Community notes