Skip to content
CAI
Software that uses CAICheck a score

fslaborg/Deedle

55.5

Adequate · 23 September 2026

27.4k

lines of production code

F#

primary language

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Deedle is a data analysis library for F\# and C\# that provides core data structures, specifically Frames and Series, for tabular data manipulation. It supports reading and writing data from various formats including CSV, Excel, Apache Parquet, and Apache Arrow, with optimizations for lazy loading and virtual indexing to handle large datasets efficiently. The system also integrates with external numerical and machine learning ecosystems, offering connectors for MathNet.Numerics and ML.NET to perform statistical analysis and machine learning pipelines directly on Deedle data structures.

How it got here

2013 — Core library architecture and test infrastructure

12 changes.

This period focused on establishing the foundational architecture of the Deedle data analysis library, introducing core data structures like Frame and Series alongside advanced features such as virtual indexing and lazy evaluation. Significant effort was also dedicated to building a comprehensive test suite across F\# and C\# to validate core operations, I/O formats, and performance characteristics, supported by a major overhaul of the repository's build system and dependency management.

2014–2026 — integration and performance expansion

19 changes.

This period focused on expanding Deedle's ecosystem by adding integration packages for Apache Arrow, Apache Parquet, Microsoft ML.NET, and Excel, alongside internal refactoring of CSV parsing and MathNet dependencies. Significant effort was also directed toward performance optimization through the introduction of virtual lazy loading for Parquet files and the establishment of a comprehensive BenchmarkDotNet suite to validate these operations.

Features

Add Deedle.Parquet component for Apache Parquet read/write support

A new Deedle.Parquet library is introduced, enabling users to read and write Deedle Frames to Apache Parquet files using the Parquet.Net library. This component handles the serialization and deserialization of frame data, mapping .NET types to Parquet DataFields and supporting nullable values for missing data across numeric, boolean, string, and date/time types.

src/Deedle.Parquet · high confidence

Add Excel read and write capabilities for Deedle frames

This change introduces two new libraries, Deedle.ExcelReader and Deedle.ExcelWriter, enabling users to import and export Deedle data frames to Excel files. The reader (Deedle.ExcelReader) uses the ExcelDataReader library to support both .xls and .xlsx formats, allowing users to read the first worksheet, specific sheets by name or index, and list available sheet names via functions like Frame.readExcel and Frame.readExcelSheet. The writer (Deedle.ExcelWriter) uses the MiniExcel library to export frames to .xlsx files, supporting writing to a single sheet, named sheets, multiple sheets in one file, and direct stream output via functions like Frame.writeExcel and Frame.writeExcelSheets. Both libraries provide F\# module extensions and C\#-friendly static methods for cross-language usability.

src/Deedle.ExcelReader, src/Deedle.ExcelWriter · high confidence

Deedle library integration and core data structure implementation

This change introduces the Deedle data analysis library into the project, providing core data structures such as \Frame\ and \Series\ for tabular data manipulation. The implementation includes a purely functional Binomial Heap for efficient minimum-finding operations, a \LinearIndex\ for fast key-based lookups in ordered data, and foundational types like \OptionalValue\ to handle missing data. Additionally, it brings in runtime support from F\# Data, including HTTP client utilities, file system watchers for live updates, and a pluralization service, enabling robust data ingestion and interactive formatting capabilities.

Deedle · high confidence

Initial Excel integration for reading, writing, and syncing Deedle data

Adds the Deedle.Excel module, enabling users to read and write Deedle Frames and Series to Excel spreadsheets via NetOffice. This includes functionality to open workbooks, manage sheets, and apply table styles. A key feature is the ability to keep Deedle data synchronized with Excel sheets, allowing changes in F\# to automatically update the corresponding Excel ranges.

Deedle.Excel · high confidence

Initial release of Deedle data frame library

This change introduces the Deedle library, providing a comprehensive data frame and series structure for F\# and C\#. It includes core modules for constructing and manipulating frames (FrameModule, FrameExtensions), handling delayed/lazy data sources (DelayedSeries), and performing statistical operations (FrameStatsExtensions). The library supports reading CSV data from files, streams, and HTTP URLs, and offers extensive functionality for joining, merging, grouping, and reshaping data.

src/Deedle · high confidence

Internal F\# Data runtime components added to Deedle

Deedle now includes internal copies of F\# Data runtime modules (Caching, NameUtils, StructuralInference, StructuralTypes, TextConversions, and TextRuntime) to support its own data provider generation. These additions provide the underlying infrastructure for type inference, text parsing, and caching that Deedle uses internally, marking these F\# Data types as internal to keep them private to the Deedle library.

src/Deedle/FSharp.Data/CommonRuntime · high confidence

Introduce ArrayVector and unified vector builder infrastructure

The library now uses a dedicated \ArrayVector\ implementation to store vector data in continuous memory blocks, automatically switching between dense and sparse representations based on the presence of missing values. A new \IVectorBuilder\ interface and \ArrayVectorBuilder\ provide a unified mechanism for constructing vectors, handling operations like filling missing values, relocating data, and dropping ranges. This change also introduces \VectorData\ types (\DenseList\, \SparseList\, \Sequence\) to expose vector contents efficiently and adds \Vector\ helper modules for F\# and C\# to create vectors from arrays or sequences, simplifying data creation for users.

src/Deedle/Vectors · high confidence

Introduce virtual Parquet reading with lazy column loading

Added \VirtualParquetSource.fs\ to the Deedle.Parquet library, enabling the \Virtual.ReadParquet\ API. This new capability allows users to read Parquet files as virtual frames, where columns are loaded lazily on demand rather than reading the entire file into memory at once. The implementation supports various data types (float, int, string, datetime, etc.) and allows specifying an index column and search columns via \VirtualReadParquetOptions\.

Deedle.Parquet · high confidence

Introduces virtual indexing and hierarchical multi-key support

The library now supports virtual (lazy) indices for DataFrames and Series, allowing operations like merging, slicing, and resampling to work without materializing the underlying data into memory. This is enabled by new \VirtualOrderedIndex\ and \VirtualOrdinalIndex\ implementations in the \Deedle.Indices\ namespace. Additionally, hierarchical multi-key indexing is introduced via \ICustomKey\ and \ICustomLookup\ interfaces, along with helper functions (e.g., \Lookup1Of2\, \LookupAnyOf3\) to match keys at specific levels of tuple-based hierarchies.

src/Deedle/Indices · high confidence

New Apache Arrow integration for Frame and Series I/O

The new Deedle.Arrow module enables conversion between Deedle Frames/Series and Apache Arrow RecordBatches, along with reading and writing Arrow IPC file and stream formats. This adds support for serializing common .NET types (numeric, boolean, string, and DateTime/DateTimeOffset) to Arrow types and deserializing them back, allowing users to exchange data with Arrow-compatible systems.

src/Deedle.Arrow · high confidence

New Deedle.MicrosoftML package for ML.NET integration

A new \Deedle.MicrosoftML\ package has been added, providing seamless conversion between Deedle Frames and ML.NET \IDataView\. Users can now convert frames to data views using \Frame.toDataView\ and \Frame.ofDataView\, and apply ML.NET transformers or estimators directly to frames via \Pipeline.applyTransformer\, \fitEstimator\, \fitTransform\, and \fitTransformOn\. The implementation supports scalar types (float, float32, int32, int64, bool, string) and fixed-length float32 vector columns, enabling ML.NET pipelines to operate directly on Deedle data structures.

src/Deedle.MicrosoftML · high confidence

Architecture

Introduce internal addressing and range abstractions for BigDeedle

This change adds new internal modules (\Address\, \Ranges\, \Deque\) to the \Deedle.Common\ library to support the BigDeedle architecture. It defines an \Address\ type (based on \int64\) and \IAddressingScheme\ interfaces to decouple index key mapping from vector storage, allowing for different addressing schemes like partitioned offsets. It also introduces \RangeRestriction\ types and a \Ranges\<'T\>\ abstraction to efficiently manage sub-ranges of ordinal indices, enabling optimizations for slicing and merging operations without fully materializing data. A new \Deque\ implementation provides a fast, mutable double-ended queue for internal statistical calculations.

src/Deedle/Common · high confidence

Repository infrastructure and build system overhaul

The repository has been restructured with new configuration files to standardize development and build processes. An \.editorconfig\ enforces 2-space indentation for F\# and XML files. A new \Directory.Build.props\ centralizes versioning by parsing \RELEASE\_NOTES.md\, enables SourceLink for debuggable NuGet packages, and configures deterministic builds in CI. The solution file (\Deedle.sln\) has been updated to include new projects such as \Deedle.Arrow\, \Deedle.Parquet\, \Deedle.ExcelReader\, \Deedle.ExcelWriter\, and \Deedle.MicrosoftML\. Build scripts (\build.sh\, \build.ps1\) now use Paket for dependency management and fsdocs for documentation, while \global.json\ targets the .NET 10 SDK. Documentation and contribution guidelines have been added via \AGENTS.md\ and \CONTRIBUTING.md\.

(repo-wide) · high confidence

Behavioural changes

2 commits (0 fixes) modifying misc

A change to existing behaviour in misc — 2 commits, 2 files.

misc · medium confidence · unverified

Internal CSV parsing engine added to Deedle

Deedle now includes its own internal implementation of the F\# Data CSV runtime components (CsvFile, CsvRow, CsvReader, and CsvInference) within the src/Deedle/FSharp.Data/Csv directory. This change embeds the CSV parsing, schema inference, and type-provider logic directly into the library, marking these types as internal to Deedle rather than relying on an external F\# Data package reference. Users can continue to use existing CSV loading and parsing APIs, but the underlying engine is now part of Deedle's own codebase.

src/Deedle/FSharp.Data/Csv · high confidence

Rename Deedle.Math to Deedle.MathNetNumerics

The Deedle.Math namespace has been renamed to Deedle.MathNetNumerics. Existing code using Deedle.Math types (such as Frame, Series, LinearAlgebra, Matrix, Stats, Finance, and their extensions) will continue to work but will show deprecation warnings; users should update their imports to use the new Deedle.MathNetNumerics namespace. The functionality itself remains unchanged, with all types now residing under the new namespace.

Deedle.MathNetNumerics, src/Deedle.MathNetNumerics · high confidence

Renamed Excel sample script and added dependency references

The Excel integration sample script has been renamed from Excel.fsx to Deedle.Excel.Sample.fsx to better reflect its purpose. Additionally, a new paket.references file was added to explicitly declare dependencies on FSharp.Core, NetOfficeFw.Core, and NetOfficeFw.Excel, ensuring the sample can run out of the box with the correct libraries.

src/Deedle.Excel · high confidence

Test coverage

Add BenchmarkDotNet performance benchmark suite; Added C\# test coverage for Deedle core, Arrow, Parquet, and Excel readers; Added comprehensive test suite for Frame operations and virtual data structures; Added test infrastructure and sample data generation for Arrow and Parquet modules; Added test infrastructure for virtual data sources and instrumentation; Added test suite for Deedle.Arrow IPC I/O and type conversions; Added test suite for Deedle.MathNetNumerics integration; Added test suite for Deedle.Parquet round-trip and type support; Added tests for Deedle.MicrosoftML integration; Added tests for Excel reading and writing capabilities; Added virtual preservation tests and Parquet test data; Expanded test coverage for Deedle core components; Updated performance test assets and results for versions 0.9.12, 1.0.0, and 1.1.1-beta.

Dependencies

Upgrade to .NET 10 and update core dependencies

The project has been upgraded to target .NET 10.0 across all source and test projects. Key dependency updates include FSharp.Core to version 10.1.201, FSharp.Data to 8.1.4, MathNet.Numerics to 5.0, and NUnit to version 4 (with FsUnit 7.1.1). The dependency management system has been standardized on Paket, introducing a new paket.dependencies file and lockfile to manage packages such as Apache.Arrow, Parquet.Net, and BenchmarkDotNet.

(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 52 → 55 (+3.6)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 49 → 64 (+14.9)
  • Architecture 53 → 54 (+0.7)
  • Maturity 70 → 70 (-0.3)
  • Readiness 53 → 50 (-3.2)
  • Security 52 → 74 (+21.3)

Resolved (71)

  • BarePragmaDisable (tests/Deedle.CSharp.Tests/ArrowTests.cs)
  • BarePragmaDisable (tests/Deedle.CSharp.Tests/ExcelReaderTests.cs)
  • BarePragmaDisable (tests/Deedle.CSharp.Tests/Frame.cs)
  • BarePragmaDisable (tests/Deedle.CSharp.Tests/ParquetTests.cs)
  • BarePragmaDisable (tests/Deedle.CSharp.Tests/Series.cs)
  • Duplicated block (10 lines × 2) (src/Deedle.Parquet/Parquet.fs)
  • Duplicated block (10 lines × 2) (src/Deedle/Vectors/VirtualVector.fs)
  • Duplicated block (10 lines × 3) (src/Deedle/FrameModule.fs)
  • Duplicated block (11 lines × 2) (src/Deedle/FrameModule.fs)
  • Duplicated block (12 lines × 2) (src/Deedle/Common/Common.fs)
  • Duplicated block (12 lines × 6) (src/Deedle/FSharp.Data/Net/Http.fs)
  • Duplicated block (15 lines × 2) (src/Deedle/FrameModule.fs)
  • Duplicated block (16 lines × 2) (src/Deedle.Arrow/Arrow.fs)
  • Duplicated block (16 lines × 2) (src/Deedle/Stats.fs)
  • Duplicated block (18 lines × 2) (src/Deedle.Parquet/Parquet.fs)
  • Duplicated block (5 lines × 10) (src/Deedle.Arrow/Arrow.fs)
  • Duplicated block (5 lines × 2) (src/Deedle.Arrow/Arrow.fs)
  • Duplicated block (5 lines × 2) (src/Deedle/FrameExtensions.fs)
  • Duplicated block (5 lines × 2) (src/Deedle/FrameExtensions.fs)
  • Duplicated block (5 lines × 2) (src/Deedle/FrameExtensions.fs)
  • …and 51 more

New (107)

  • CommentedOutCode (tests/Deedle.CSharp.Tests/Series.cs)
  • CsvParsing.splitCsvLine (cognitive 17) (src/Deedle/VirtualCsvSource.fs)
  • CycleInference.tryDetectOptional (cognitive 17) (src/Deedle/VirtualLookupRange.fs)
  • Documentation: no architecture or design documentation (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Duplicated block (11 lines × 2) (src/Deedle/FrameModule.fs)
  • Duplicated block (12–15 lines × 2) (src/Deedle/FrameUtils.fs)
  • Duplicated block (13 lines × 2) (src/Deedle.MathNetNumerics/Finance.fs)
  • Duplicated block (13–14 lines × 6) (src/Deedle/FSharp.Data/Net/Http.fs)
  • Duplicated block (14–15 lines × 2) (src/Deedle/VirtualFrame.fs)
  • Duplicated block (14–15 lines × 3) (src/Deedle/FrameModule.fs)
  • Duplicated block (15 lines × 2) (src/Deedle/VirtualFrame.fs)
  • Duplicated block (15 lines × 2) (src/Deedle/VirtualLookupRange.fs)
  • Duplicated block (15–16 lines × 2) (src/Deedle/Vectors/VirtualVector.fs)
  • Duplicated block (16 lines × 2) (src/Deedle.Arrow/Arrow.fs)
  • Duplicated block (16 lines × 2) (src/Deedle/FrameModule.fs)
  • Duplicated block (19 lines × 2) (src/Deedle/Stats.fs)
  • Duplicated block (23–24 lines × 2) (src/Deedle.Parquet/Parquet.fs)
  • Duplicated block (4–9 lines × 10) (src/Deedle.Parquet/Parquet.fs)
  • Duplicated block (5 lines × 10) (src/Deedle.Arrow/Arrow.fs)
  • …and 87 more

Changes since last survey

  • 6 commits — 6 feature/other, 0 fixes

By area

  • .github/workflows — 2 commits
  • src/Deedle — 2 commits
  • (root) — 1 commit
  • tests/Deedle.Tests — 1 commit

Notable commits

  • change: Add Iteration functions for Series and Frame (#725)
  • change: Big Deedle updates (#733)
  • change: Document agentic contribution workflow (#732)
  • change: [repo-assist] Add Frame.head/tail and Series.head/tail; add renameCol and head/tail tests (#726)
  • change: update repo assist
  • change: update repo assist

Architecture

  • Containers 0 added · 0 removed · contexts 3 added · 1 removed · edges 3 added · 0 removed

Added bounded contexts (3)

  • Deedle.Benchmarks
  • Deedle.Parquet
  • Deedle.VirtualPreservation

Removed bounded contexts (1)

  • Deedle.ExcelReader.Tests

Added dependency edges (3)

  • Deedle.Benchmarks → Deedle (coupling)
  • Deedle.Parquet → Deedle (coupling)
  • Deedle.VirtualPreservation → Deedle (coupling)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

fslaborg/Deedle 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 23 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 f18284a4b6dfc6851ac4e1b32999a9064768a9ff — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.