nshiab/simple-data-analysis
Fast DuckDB-powered TypeScript library for tabular analysis, geospatial analysis, network graph analysis, vector similarity search, AI, Google Sheets, and data visualization.
What it is: A TypeScript library for tabular, geospatial, and AI-assisted data analysis that runs on Deno, Node.js, and Bun. It wraps DuckDB (an in-process analytical database) behind a Pandas/Tidyverse-inspired chainable API, and adds optional AI features like row-by-row LLM processing, embeddings, and RAG. It was created by a computational journalist at CBC News who wanted to do data analysis and visualization entirely in JavaScript instead of switching between Python, R, and JS.
Why it matters: JavaScript has historically lagged behind Python and R for serious data work (pandas, tidyverse, GeoPandas). SDA closes that gap by:
- Performance via DuckDB – Benchmarks in the README (22M temperature records, 335K geospatial points) show SDA runs close to raw DuckDB speed while beating pandas/tidyverse/GeoPandas, with lower memory.
- One language for the whole pipeline – Analysis, geospatial joins, charts, maps, and AI enrichment all happen in TypeScript without switching ecosystems.
- Lazy loading and query fusion – Core transformations queue up and get fused into single SQL statements, reducing round trips. AI/Google/charting dependencies only load when those specific methods are called, so core-only users don't pay the startup cost.
- Built-in AI features (in the extended package):
aiRowByRow()sends column values to an LLM and stores structured responses (e.g., extracting country + continent from a city name),aiEmbeddings()converts text to vectors, and it supports clustering (HDBSCAN), hybrid search, RAG-style question answering, and natural-language queries. Google Gemini, Vertex AI, or local Ollama models are configurable via.env. - Public data sources – Direct loaders for Statistics Canada tables and OpenStreetMap (local files or Overpass queries), with local caching for reproducibility.
How it works under the hood: SDA executes SQL in DuckDB via duckdb-node-neo, and uses DuckDB extensions (spatial for geospatial ops, plus fuzzy matching, full-text search, vector indexes) loaded lazily. The API is synchronous and chainable for transformations; you only await the final observer method (like .log(), .writeData(), or getting results).
Example (from README): Load a CSV of Canadian weather stations, rename columns, drop missing values, compute mean temperature per station, sort, print, and export:
const sdb = new SimpleDB();
const data = await sdb
.newTable("temperatures")
.loadData(".../dailyTemperatures.csv")
.renameColumns({ t: "temperature", id: "station" })
.removeMissing({ columns: "temperature" })
.summarize({
columns: "temperature", by: "station", stats: "mean", decimals: 2,
})
.sort({ mean: "desc" })
.log();
await data.writeData("output/averageTemperatures.csv");
await sdb.close();
Who it's for: Data journalists, analysts, and developers who prefer JavaScript/TypeScript and need to handle large datasets, do geospatial joins, produce charts/maps, or enrich data with LLMs — without learning a second data language.
Caveats from the README: This is a real, substantial library, but it is not a full dataframe replacement for every Python use case; the AI features require API keys (Gemini/Vertex/Ollama) and the README notes that JSR documentation currently omits inherited methods (a known upstream limitation). Installation is via JSR or npm for Node/Bun/Deno, and there's a companion scaffolding tool (setup-data-project) to start new projects.
Related
- Project
- Project
- Project
- Project
- Project