Library / SDK
square/crossfilter avatar
square/crossfilter

crossfilter: the linked-brushing library that reached version 1.3.12 and stopped

Fast n-dimensional filtering and grouping of records.

6,183 stars1,268 forksJavaScriptNOASSERTION

At a glance

What is it?
Square built crossfilter to make live histograms and top-K lists over a million records feel instant. The library still does, and the README tells you plainly that nothing more is coming.
Who is it for?
crossfilter is worth reaching for when the dataset is already in memory, the dimensions are numeric, and you want coordinated views that respond while a slider is still moving. Its sorted indexes and bitset tricks are the reason a million records can be regrouped in a fraction of the time a naive reduce would take.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Activity is slowing. The repository last received commits 7 months 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 October 23, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • square/crossfilter6,183 ★ · -3
Star history
Repository2026-10-082026-10-23
square/crossfilter6.2k6.2k

-3 Stars in the last 15 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Dimensions, filters and groups over records in memory

Crossfilter is a JavaScript library for exploring large multivariate datasets in the browser. The model is small enough to hold in your head and specific enough that you can predict its cost. You create a dimension from a field in your records, you add filters to that dimension, and you define groups that reduce the records passing the current filter set. Live histograms and top-K lists are then just groups you re-read whenever a filter changes.

The performance argument in the README rests on two observations. Most interactions touch a single dimension at a time, and within one dimension the filter values usually move in small increments. That means a full pass over every record is wasted work. Crossfilter uses sorted indexes plus bitset manipulation so that when a filter value shifts slightly, only the affected records are reconsidered.

The claim attached to that design is interaction under 30 milliseconds on datasets of a million records or more. The README says the library was built to power analytics for Square Register, which is the sort of workload where a merchant slices payment history and expects the charts to keep up with the mouse. Both the target and the method are stated plainly, and the benchmark harness is still in the repository tree under `test/`.

So the library is not a database and does not pretend to be one. It operates on records you have already loaded, and the payoff is entirely in the interaction loop.

A README that announces its own conclusion

The Status section is unusually direct. It says crossfilter is not under active development, maintenance or support by Square, by the original author Mike Bostock, or by the current contributors Jason Davies and Tom Carden. It then says genuine bug fixes and pull requests are still welcome while treating the current API and feature set, around version 1.3.12, as essentially complete.

The same section names where the work went instead. A separate Crossfilter Organization on GitHub hosts a maintained fork, the README says that fork is already used by DC.js, and its contributors are working on API and performance changes aimed at current JavaScript engines. It closes by stating there are no plans to merge or publish new versions under the original Square repository or npm package.

GitHub reports the repository was last pushed to on 2026-03-04, and it is not archived. Those two facts sit next to each other without a contradiction to resolve: commits still land on this repository while no new version is published from it. The practical consequence is that the `crossfilter` package on npm is frozen at the 2015 code, and anyone who needs different behaviour has to take the fork rather than wait for a release here. Judging which one you want comes down to whether you need the exact API Square shipped or a maintained one.

Three sources for the license and no agreement

The license is the one place where the repository contradicts itself three ways. GitHub reports NOASSERTION for the license, which is what the API returns when it cannot map a detected license file to a known identifier. The README carries a badge reading Apache 2.0 that links to the raw LICENSE file. The LICENSE file is in the repository tree, and the README states the library is available under the Apache License.

None of those three cancel each other out, and you do not have to pick a winner to know where you stand. The badge and the LICENSE file agree with each other and with the prose, which is the agreement that carries legal weight, since a license is the text of the file rather than a field in a database. The NOASSERTION value is a gap in GitHub's detection rather than a claim that the code is unlicensed.

If you are building this into something you intend to ship, read `LICENSE` in the repository. That is the document that governs, and both the badge and the README point you to it. Note separately that the maintained fork carries its own terms, so if you take the fork instead of the published package, that is the license you need to read.

The build is a shell script wearing a Makefile

There is no bundler here. The Makefile concatenates the files under `src/` into a single `crossfilter.js`, wraps them in a module closure, stamps the version string pulled from package.json, and marks the result read only with `chmod a-w`. A second rule pipes that file through uglify to produce `crossfilter.min.js`. Both generated files are committed to the repository, so you can use the library without building anything.

The file list in the Makefile is the best map of the internals: `identity`, `permute`, `bisect`, `heap`, `heapselect`, `insertionsort`, `quicksort`, `array`, `filter`, `null`, `zero`, `reduce`, and `crossfilter`. The sorting and selection routines sit next to the filter and reduce code because the incremental strategy depends on them. If you are trying to understand the performance claim, those filenames are where the argument lives.

Two convenience targets exist for working on the library itself:

bash
npm test
node test/benchmark.js

The first runs the vows suite declared in package.json, and the second runs the benchmark harness, which is the closest thing in the repository to a check on the sub-30-millisecond claim.

Dependency versions that date the project precisely

package.json lists three development dependencies and they are from a specific era: d3 at version 3, vows at 0.7.0, and uglify-js at 2.6.0. The test script points at a local vows binary, and the build script calls uglify directly. There is no test framework configuration, no transpiler, and no lock file in the tree.

The build badge in the README points at Travis CI, a service that has been gone from the public GitHub integration landscape for years. That is not a criticism so much as a timestamp. Combined with the 2015 release date and the d3 major version, it tells you that installing this project today means running a 2015 toolchain against a current Node, which is where friction is most likely to appear rather than in the library itself.

The author and contributor fields are worth noting too. package.json credits Mike Bostock as author, Jason Davies as a contributor, and Tom Carden as a maintainer, which matches the three people the README names when it says the project is not under their maintenance. The credits are accurate about who built it, and the Status section is accurate about who is not running it now.

What a new project should actually do with it

The library is still a good fit for a specific shape of problem: a dataset already in the browser, numeric dimensions you want to brush across several coordinated views, and an expectation that interactions stay under a frame or two. Payment history, order volume by hour, clickstream segments with numeric dimensions, all of that is the shape it was tuned for, and the API for it has not changed.

It is a poor fit if you need data loaded on demand, if your fields are mostly strings, or if you need the library to stay in step with a modern toolchain without doing that work yourself. The README is candid that the feature set is considered complete, which in practice means you are choosing a finished artifact rather than a growing one.

The one thing worth doing before committing is checking which of the two codebases you actually want, since they are not interchangeable and the npm package will not tell you about the fork. Decide that first, read the LICENSE of whichever you pick, and then judge the performance question against the benchmark harness in `test/` rather than against a claim in a badge.

Editorial conclusion

crossfilter is worth reaching for when the dataset is already in memory, the dimensions are numeric, and you want coordinated views that respond while a slider is still moving. Its sorted indexes and bitset tricks are the reason a million records can be regrouped in a fraction of the time a naive reduce would take. What you will not get is movement on the Square side: version 1.3.12 dates from October 2015, the README states no further releases are planned under this repository or its npm package, and the dependency versions in package.json place the build chain in the early 2010s. Install `crossfilter` from npm if you want the exact library Square shipped, or start from the fork under the Crossfilter Organization if you need changes. The LICENSE file in the repository settles the terms, whatever the license field says.

Frequently asked questions

Is crossfilter still maintained, and should I use it in a new project?

The Square repository states that it is not under active development or support and that no new versions are planned under the original repository or npm package, which leaves the published package at version 1.3.12. A maintained fork exists under the Crossfilter Organization and is already used by DC.js, so a new project that needs changes should start there instead of waiting for a release.

How does crossfilter stay fast when a filter changes?

Most interactions touch one dimension and move the filter value in small increments, so the library updates sorted indexes and bitsets rather than reducing every record again. That incremental path is what the README credits for interaction under 30 milliseconds on a million records or more.

What license does crossfilter use?

GitHub reports NOASSERTION for the repository license, which reflects its own detection failing to map the file to a known identifier. The README badge reads Apache 2.0, the README text says the library is available under the Apache License, and a LICENSE file is committed, so the file in the repository is the document to read.

Does crossfilter replace a database or a charting library?

It does neither. Crossfilter holds records you have already loaded, filters and groups them in memory, and hands the results to whatever renders the charts, which is why it was built for Square Register analytics. It is a data layer for interaction speed, not storage and not visualisation.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. square/crossfilter on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/square-crossfilter.svg)](https://hysenlabs.com/projects/square-crossfilter)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/square-crossfilter.svg)](https://hysenlabs.com/projects/square-crossfilter)

Was this useful?