medialab/xan
59.4
Adequate · 30 September 2026
47.9k
lines of production code
Rust
primary language
2
measurements over time
What this system is
Xan is a high-performance, SIMD-accelerated command-line tool for CSV data manipulation and analysis, written in Rust. It provides a comprehensive suite of data processing commands alongside a powerful expression engine, Moonblade, which supports complex aggregations, windowing functions, and HTML scraping. The system also includes specialized infrastructure for handling graph data structures and Parquet files, enabling efficient pipeline processing and statistical computation.
How it got here
2014 — Initial release and infrastructure expansion
5 changes.
This period marks the initial release of the xan CLI tool, featuring a major rebrand from xcsv and a comprehensive dependency overhaul to support Rust 2024. The work established foundational documentation and citation infrastructure while introducing core capabilities for graph analysis, Parquet data support, and pipeline processing. Extensive test coverage was added for core CSV manipulation commands to ensure stability alongside these new features.
2024–2026 — Moonblade engine overhaul
8 changes.
This period focused on a comprehensive rewrite of the Moonblade expression engine, introducing a Pest-based parser and a modular aggregation architecture with advanced statistical capabilities. The work also involved refactoring the type system for better temporal support and optimizing core collection primitives, alongside adding automation scripts to streamline development workflows.
Features
Initial release of xan with Zenodo metadata and documentation
This commit introduces the initial version of the \xan\ CLI tool (renamed from \xcsv\/\xsv\), providing a high-performance, SIMD-accelerated CSV data manipulation command line interface written in Rust. It establishes the project's foundational documentation, including a comprehensive README with installation instructions for various package managers (Cargo, Homebrew, Nix, etc.), a CHANGELOG detailing features and breaking changes from version 0.62.0 onwards, and an AUTHORS file. Additionally, it adds \.zenodo.json\ to enable formal citation of the software via Zenodo, listing the project's creators and affiliations.
(repo-wide) · high confidence
New aggregation functions and statistical capabilities
The moonblade aggregation engine now supports a wider range of statistical computations, including geometric mean, harmonic mean, and root-mean-square (RMS) via Welford's algorithm, as well as approximate cardinality and quantiles using HyperLogLogPlus and TDigest. Users can also access new aggregators for all/any boolean checks, first/last values, and numeric extents with argmin/argmax tracking. The system introduces sparkline generation for number distributions and temporal granularity inference, alongside improved precision for sums using the Kahan-Babuska algorithm.
src/moonblade/agg/aggregators · high confidence
New automation scripts for documentation, releases, and segmentation testing
Three new shell scripts have been added to the repository to streamline development workflows. The \docs.sh\ script automates the generation of command-line help documentation and Moonblade reference materials by invoking the built binary. The \release.sh\ script simplifies the publishing process by handling version retrieval, cargo publishing, and git tagging in a single step. Additionally, \test\_segmentation.sh\ provides a functional test suite for file segmentation logic, iterating through various chunk configurations to verify data integrity.
scripts · high confidence
New graph, parquet, and processing infrastructure
The application now includes core infrastructure for graph analysis, Parquet data support, and pipeline processing. A new \graph.rs\ module implements graph data structures, degree mapping, and GEXF serialization (supporting both 1.2 and 1.3 namespaces). Parquet file reading is enabled via a new \parquet.rs\ module that handles schema projection and type mapping. Additionally, a \processing.rs\ module introduces a \Children\ abstraction for managing child processes in pipelines, including a \check\ method for error handling, and a \ratatui.rs\ module provides utilities for rendering TUI frames to stdout.
src · high confidence
New optimized collection primitives and hash map backend
The \src/collections\ module now provides several new data structures to improve performance and functionality: \ClusteredInsertHashmap\ for faster lookups on clustered keys, \ContextBuffer\ for managing before/after context windows, \TopKHeap\ for efficient top-k selection, and \IncrementalId\ for generating unique IDs. Additionally, the module's default \HashMap\ and \HashSet\ types have been switched to use the \ahash\ crate (via \AHashMap\/\AHashSet\) for improved hashing performance.
src/collections · high confidence
Architecture
Moonblade functions refactored into modular submodules
The moonblade function library has been reorganized from a single monolithic file into distinct submodules (fmt, fuzzy, io, maps, ops, sequences, strings, temporal, utils, web). This structural change improves code maintainability and allows for clearer separation of concerns across formatting, file I/O, data manipulation, and temporal operations, while preserving the existing public API surface for users.
src/moonblade/functions · high confidence
New modular aggregation and windowing engine for Moonblade
The \src/moonblade/agg\ module has been restructured into a new, modular architecture that separates aggregation logic into distinct components: \program.rs\ for defining aggregation programs (including group-by, pivot, and along-columns variants), \stats.rs\ for descriptive statistics (mean, variance, quantiles, frequencies), and \window.rs\ for window functions (rolling sums/averages, cumulative min/max, ranking, lead/lag). This change introduces a unified \Aggregator\ enum and \AggregationProgram\ interface, enabling more maintainable and extensible aggregation pipelines while supporting parallel execution and memory-optimized layouts for existing and new functions like covariance, correlation, and geometric/harmonic means.
src/moonblade/agg · high confidence
Behavioural changes
1674 commits (418 fixes) modifying src/cmd
A change to existing behaviour in src/cmd — 1674 commits (418 fixs), 67 files.
src/cmd · medium confidence · unverified
Moonblade expression engine rewritten with Pest parser and new program types
The Moonblade expression engine has been completely rewritten, replacing the previous implementation with a new Pest-based parser (grammar.pest) and a fresh interpreter architecture. This change introduces new program types including \ChooseProgram\ (for handling current/new record comparisons), \SelectionProgram\ (for named and plural column selections), and \ScrapingProgram\ (for HTML scraping with CSS selectors and text extraction). The parser now supports a richer syntax including list and map literals, lambda expressions, named arguments, pipeline operators, and improved string/regex handling. Error reporting has been restructured with dedicated \ConcretizationError\ and \EvaluationError\ types for clearer diagnostics.
src/moonblade · high confidence
Moonblade type system refactored with new argument handling and temporal support
The moonblade types module has been restructured to introduce a new \BoundArgument\ system for more efficient argument passing and a \FunctionArguments\ API that supports named arguments, variadic parameters, and arity validation. \DynamicValue\ now includes dedicated temporal variants (\Zoned\, \DateTime\, \Date\, \Time\, \Span\) powered by the \jiff\ library, alongside a new \DynamicNumber\ type for numeric operations. The \HeadersIndex\ has been updated to support negative indexing and duplicate header names, while \DynamicValue\ serialization and deserialization have been modernized to use \TryFrom\ and improved visitor patterns.
src/moonblade/types · high confidence
Test coverage
Added test resources for text scraping and HTML parsing; Expanded test coverage for core CSV manipulation commands.
Dependencies
Major dependency overhaul and project rebrand to xan
The project has been renamed from xcsv to xan, updated to Rust edition 2024 with a minimum supported Rust version of 1.88.0, and its dependency tree has been significantly expanded and modernized. Key updates include upgrading simd-csv to 0.14.0, paltoquet to 0.12.0, and calamine to 0.36.1, while adding support for new formats and features via crates like bgzip, npyz, and parquet. The Cargo.lock file has been regenerated to reflect these changes, introducing a comprehensive list of new dependencies such as ahash, bstr, and fast-float2, and removing older git-based dependencies in favor of versioned crates.io packages.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 69 → 59 (-10.0)
- Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 73 → 73 (-0.1)
- Architecture 100 → 89 (-11.1)
- Maturity 75 → 75 (+0.0)
- Readiness 74 → 45 (-29.8)
- Security 61 → 69 (+8.6)
Resolved (19)
- Args::convert_parquet (cyclomatic 24) (src/cmd/from.rs)
- Documentation: no contributor guidance (README.md)
- Documentation: no installation or build instructions
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Duplicated block (14 lines × 2) (src/select.rs)
- Duplicated block (9 lines × 2) (src/moonblade/functions/temporal.rs)
- Hotspot: src/cmd/cat.rs (src/cmd/cat.rs)
- Hotspot: src/cmd/from.rs (src/cmd/from.rs)
- Hotspot: src/cmd/spark.rs (src/cmd/spark.rs)
- Medium CVE: [GHSA redacted] (Cargo.lock)
- Medium advisory (unmaintained): RUSTSEC-2025-0057 (Cargo.lock)
- Medium advisory (unsound): RUSTSEC-2026-0002 (Cargo.lock)
- Medium advisory (unsound): RUSTSEC-2026-0097 (Cargo.lock)
- Medium advisory (unsound): RUSTSEC-2026-0253 (Cargo.lock)
- Medium vulnerability: RUSTSEC-2026-0194 (Cargo.lock)
- Medium vulnerability: RUSTSEC-2026-0194 (Cargo.lock)
- Members sharing a duplicated core (4 members, 50+ identical tokens) (src/cmd/parallel.rs)
- Near-duplicate member pair (42 shared lines) (src/moonblade/functions/temporal.rs)
New (32)
- Args::bivar (cognitive 17) (src/cmd/matrix.rs)
- Args::convert_ndjson (cognitive 28) (src/cmd/from.rs)
- Documentation: no project overview (docs/cmd/complete.md)
- Documentation: no project overview (docs/cmd/count.md)
- Duplicated block (13 lines × 2) (src/select.rs)
- Duplicated block (13 lines × 2) (src/select.rs)
- Duplicated block (15 lines × 2) (src/cmd/matrix.rs)
- Duplicated block (8 lines × 2) (src/moonblade/functions/temporal.rs)
- End-of-life runtime: Rust 1.88
- FileTooLong: src/json.rs (src/json.rs)
- Flaky test: xan::tests.test_select::select_all::headers
- Flaky test: xan::tests.test_select::select_not::headers
- Flaky test: xan::tests.test_select::select_range::headers
- Flaky test: xan::tests.test_select::select_range_multi_idx::headers
- Flaky test: xan::tests.test_select::select_range_no_start::headers
- Flaky test: xan::tests.test_select::select_range_no_start::no_headers
- Flaky test: xan::tests.test_sort::sort_check_reverse
- Flaky test: xan::tests.test_sort::sort_count_empty
- Flaky test: xan::tests.test_sort::sort_count_one_group
- Hotspot: src/cmd/headers.rs (src/cmd/headers.rs)
- …and 12 more
Changes since last survey
- 26 commits — 21 feature/other, 5 fixes
By area
- (root) — 12 commits
- src/cmd — 8 commits
- docs/cmd — 2 commits
- src/moonblade — 2 commits
- (repo) — 1 commit
- src/config.rs — 1 commit
Notable commits
- fix: Adding chars & graphemes moonblade functions Fix #1170
- fix: Adding the ord & chr moonblade functions Fix #1171
- fix: Clarifying filter example in quick tour Fix #1157
- fix: numfmt-related utils to avoid allocating needlessly Fix #1047
- fix: xan from --model now renames columns Fix #1167
- change: Adding easy way to pass null-byte to -d
- change: Adding xan from -f=parquet -s/--select
- change: Adding xan matrix bivar
- change: Better xan headers parquet integration wtf parquet.
- change: Clarifying xan from help wrt compressed inputs
- change: Clippy pass
- change: Config::is_parquet
- change: Documenting parquet integration in README
- change: Drafting parquet utils
- change: Dropping parquet feature Parquet integration is now the default
- change: Merge branch 'master' into parallel-ndjson
- change: Modernizing code as per clippy recommendations
- change: Optimizing xan from -p
- change: Parallel xan from -f ndjson Related to #1156
- change: Refactoring ParquetReader for later
- …and 6 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
medialab/xan was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 30 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 866e7fb2a424ed1dbd7baeff981a86ef86c55e95 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-cb25ca4feafa.