Abstract / Overview
dataframe-js is an immutable tabular data library for JavaScript with a SQL- and FP-inspired API for selecting, filtering, grouping, joining, and exporting data. It runs in Node.js and the browser, and ships optional modules for statistics, matrix math, and ad-hoc SQL over registered tables.
Key points:
Core type:
DataFrameof rows and named columns. Immutability means every operation returns a new frame.IO helpers:
fromCSV/TSV/PSV/JSON/TextandtoCSV/TSV/PSV/JSON/Text.Ecosystem modules:
stat,matrix, andsql.Maintenance status: repository archived “No Maintenance Intended” on August 17, 2024; the latest published line shows 1.4.4. Plan accordingly.
TypeScript support exists via
@types/dataframe-js.
Conceptual Background
A DataFrame provides labeled, columnar operations familiar to users of pandas or dplyr: projection (select), row predicates (filter), set operations (union, distinct), joins, and groupBy(...).aggregate(...). The API favors composable, side-effect-free chains.
Useful context and signals for technology choice:
dataframe-js has ~462 GitHub stars and is archived; treat it as stable but frozen.
The DefinitelyTyped package reports ongoing usage, indicating that downstream typings are still being used even if the core library is frozen.
If you need an actively maintained alternative, Arquero from UW’s Interactive Data Lab offers a dplyr-like API for filtering, joins, aggregation, and window functions.
Expert quotes:
“The library has verbs for data reshaping, merging, aggregating, and more,” InfoWorld on Arquero.
“Danfo.js… provides high-performance, intuitive… data structures,” TensorFlow blog.
Step-by-Step Walkthrough
Install and import
# Node
npm install dataframe-js
# or
yarn add dataframe-js// ESM
import DataFrame from 'dataframe-js';
// CommonJS
const { DataFrame } = require('dataframe-js');
// Browser (global): dfjs.DataFrame (via dist bundle)Create a DataFrame
From arrays, objects, or dictionaries:
// 1) From collection of objects
const df1 = new DataFrame(
[{ c1: 1, c2: 6 }, { c4: 1, c3: 2 }],
['c1','c2','c3','c4']
);
// 2) From table (array of arrays)
const df2 = new DataFrame(
[[1, 6, 9, 10, 12], [1, 2], [6, 6, 9, 8, 9, 12]],
['c1','c2','c3','c4','c5','c6']
);
// 3) From dictionary of columns
const df3 = new DataFrame(
{ column1: [3,6,8], column2: [3,4,5,6] },
['column1','column2']
);Load from files or URLs
// Node: absolute paths; Browser: URLs / File objects
const dfCSV = await DataFrame.fromCSV('/abs/path/file.csv');
const dfTSV = await DataFrame.fromTSV('https://example.com/data.tsv');
const dfJSON = await DataFrame.fromJSON('https://example.com/data.json');
// Browser File
// const dfFromFile = await DataFrame.fromJSON(new File([...]));Inspect and shape
dfCSV.show(5); // print first 5 rows
const [rows, cols] = dfCSV.dim(); // dimensions
const slim = dfCSV
.select('city','state','population') // projection
.distinct('city'); // de-duplicate
const filtered = dfCSV.filter(row => row.get('population') > 100000);Column transforms and missing data
// Add or modify columns immutably
const enriched = dfCSV
.withColumn('pop_thousands', row => row.set('pop_thousands',
(row.get('population') ?? 0) / 1000));
// Fill or drop missing values
const filled = enriched.fillMissingValues(0);
const cleaned = enriched.dropMissingValues();Grouping and aggregation
const grouped = dfCSV.groupBy('state');
const byState = grouped
.aggregate(group => group.count()) // one DF per group
.rename('aggregation','city_count');Joins
// inner join on two keys
const joined = dfA.innerJoin(dfB, ['city','state']);Export and convert
// To native JS
const rowsArr = dfCSV.toArray();
const objects = dfCSV.toCollection();
const dictCols = dfCSV.toDict();
// To files (Node)
await DataFrame.toCSV(true, '/abs/path/out.csv'); // overwrite=trueStatistics, matrix math, and ad-hoc SQL
// Stat module
const maxVal = dfCSV.stat.max('population');
const avgVal = dfCSV.stat.mean('population');
// Matrix module
const scaled = dfCSV.matrix.product(1.1); // multiply numeric cells
// SQL module
dfCSV.sql.register('cities'); // or DataFrame.sql.registerTable(dfCSV,'cities')
const dfQuery = DataFrame.sql.request('SELECT city, state FROM cities WHERE population > 100000');

Join the conversation! Your thoughts help the community grow.