Read, inspect, and convert SAS binary (.sas7bdat) files β from Rust code, the command line, or the browser. Converts to CSV, Parquet, Feather, and NDJSON using Apache Arrow.
The original use case was a command-line tool for converting SAS files, but the project has since expanded into a workspace of crates that can be used as a Rust library, a CLI, or compiled to WebAssembly for browser and JavaScript runtimes.
π¬ The demo above is generated from
scripts/demo.shand recorded withscripts/record-demo.sh.
The command-line tool is developed in Rust and is only possible due to the following excellent projects:
- The ReadStat C library developed by Evan Miller
- The arrow Rust crate developed by the Apache Arrow community
The ReadStat library is used to parse and read sas7bdat files, and the arrow crate is used to convert the read sas7bdat data into the Arrow memory format. Once in the Arrow memory format, the data can be written to other file formats.
π‘ Note: The ReadStat C library supports SAS, SPSS, and Stata file formats. The
readstat-syscrate exposes the full ReadStat API β all 125 functions across all formats. However, the higher-level crates (readstat,readstat-cli,readstat-wasm) only implement support for SAS.sas7bdatfiles. SPSS and Stata support is a possible future addition, but is not planned at this time β if you need those formats today, thereadstat-sysbindings already expose the complete SPSS (.sav,.zsav,.por) and Stata (.dta) C API to build on.
Convert the first 50,000 rows of example.sas7bdat to the file
example.parquet, overwriting the file if it already exists. File output uses
bounded parallel writing by default while preserving row order.
readstat convert /some/dir/to/example.sas7bdat --output /some/dir/to/example.parquet --rows 50000 --overwriteIf you have Rust installed, the easiest way to install is via cargo:
cargo install readstat-cliThe default CLI omits the substantially larger DataFusion SQL engine. To add
the --sql and --sql-file options, install with the opt-in sql feature:
cargo install readstat-cli --features sql[Mostly] static binaries for Linux, macOS, and Windows may be found at the Releases page. Release binaries use the CLI's lean default feature set and do not include SQL.
Move the readstat binary to a known directory and add the binary to the user's PATH.
Ensure the path to readstat is added to the appropriate shell configuration file.
For Windows users, path configuration may be found within the Environment Variables menu. Executing the following from the command line opens the Environment Variables menu for the current user.
rundll32.exe sysdm.cpl,EditEnvironmentVariablesAlternatively, update the user-level PATH in PowerShell (replace C:\path\to\readstat with the actual directory):
$currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
[Environment]::SetEnvironmentVariable("Path", "$currentPath;C:\path\to\readstat", "User")After running the above, restart your terminal for the change to take effect.
Run the binary.
readstat --helpThe binary is invoked using subcommands:
metadataβ writes file and variable metadata to standard out or JSONpreviewβ writes the first N rows of parsed data ascsvto standard outconvertβ converts data to CSV, Feather, NDJSON, or Parquet; the output extension selects the format, or omitted output writes CSV to stdout
Column metadata β labels, SAS format strings, and storage widths β is preserved in Parquet and Feather output as Arrow field metadata. See docs/TECHNICAL.md for details.
For a one-page visual overview see the CLI Cheatsheet (rendered). For the full CLI reference β including column selection, parallelism, memory considerations, SQL queries, reader modes, and debug options β see docs/USAGE.md.
For library, API server, and WebAssembly usage, see Examples below.
Clone the repository (with submodules), install platform-specific developer tools, and run cargo build. Platform-specific instructions for Linux, macOS, and Windows are in docs/BUILDING.md.
βΉοΈ Minimum Supported Rust Version (MSRV):
1.88(let-chains; Rust edition 2024). All published crates setrust-version = "1.88".
π» Platform Support
| Platform | Status | C library | Notes |
|---|---|---|---|
| Linux (glibc) | βοΈ Builds and runs | System iconv, system zlib | β |
| Linux (musl) | βοΈ Builds and runs | System iconv, system zlib | β |
| macOS | βοΈ Builds and runs | System libiconv, system zlib |
β |
| Windows (MSVC) | βοΈ Builds and runs | Vendored iconv, vendored zlib | MSVC supported since ReadStat 1.1.5 (no msys2 needed). Default builds use pre-generated bindings β no libclang install required. |
| Windows (GNU / MinGW) | βοΈ Builds and runs | Vendored iconv, vendored zlib | Needs a MinGW-w64 GCC (e.g. MSYS2 on Windows, gcc-mingw-w64-x86-64 when cross-compiling from Linux). Own pre-generated bindings (MSVC/GNU enum ABIs differ) β see docs/BUILDING.md. |
π Online Book (GitHub Pages) β full reference including installation, CLI usage, architecture, technical details, and memory safety.
| Document | Description |
|---|---|
| docs/ARCHITECTURE.md | Crate layout, key types, and architectural patterns |
| docs/USAGE.md | Full CLI reference and examples |
| docs/readstat-cheatsheet.html | One-page printable CLI cheatsheet (rendered) |
| docs/BUILDING.md | Clone, build, and linking details per platform |
| docs/TECHNICAL.md | Floating-point precision and date/time handling |
| docs/TESTING.md | Running tests, dataset table, fuzz testing, valgrind |
| docs/BENCHMARKING.md | Criterion benchmarks, hyperfine, and profiling |
| docs/CI-CD.md | GitHub Actions triggers and artifacts |
| docs/MEMORY-SAFETY.md | Automated memory-safety CI checks (Miri, AddressSanitizer on Linux/macOS/Windows, weekly fuzzing; Valgrind run manually) |
| docs/RELEASING.md | Step-by-step guide for publishing crates to crates.io |
| scripts/check-updates.sh | Crate dependency update checker β supply-chain quarantine, held-back/major reporting, and a bindgen advisory (--apply to update; .ps1 for Windows) |
| scripts/check-vendor-updates.sh | Read-only check for upstream updates to the vendored git submodules (ReadStat, win-iconv) β never alters the checkout (.ps1 for Windows) |
| Crate | Path | Description |
|---|---|---|
readstat |
crates/readstat/ |
Pure library for parsing SAS files into Arrow RecordBatch format. Output writers are feature-gated. |
readstat-cli |
crates/readstat-cli/ |
Binary crate producing the readstat CLI tool (arg parsing, progress bars, orchestration). |
readstat-sys |
crates/readstat-sys/ |
Raw FFI bindings to the full ReadStat C library (SAS, SPSS, Stata) via bindgen. |
readstat-iconv-sys |
crates/readstat-iconv-sys/ |
Windows-only FFI bindings to iconv (vendored public-domain win-iconv) for character encoding conversion. |
readstat-tests |
crates/readstat-tests/ |
Integration test suite (33 modules, 16 datasets). |
readstat-wasm |
crates/readstat-wasm/ |
WebAssembly build for browser/JS usage (excluded from workspace, built with Emscripten). |
For full architectural details, see docs/ARCHITECTURE.md.
The examples/ directory contains runnable demos showing different ways to use readstat-rs.
| Example | Description |
|---|---|
cli-demo |
Convert a .sas7bdat file to CSV, NDJSON, Parquet, and Feather using the readstat CLI |
api-demo |
API servers in Rust (Axum) and Python (FastAPI + PyO3) β upload, inspect, and convert SAS files over HTTP |
bun-demo |
Parse a .sas7bdat file from JavaScript using the WebAssembly build with Bun |
web-demo |
Browser-based viewer and converter β upload, preview, and export entirely client-side via WASM |
sql-explorer |
Browser-based SQL explorer β upload a .sas7bdat file and query it interactively with SQL via AlaSQL |
To use readstat as a library in your own Rust project, add the readstat crate as a dependency.
SQL support (synchronous and asynchronous DataFusion APIs) and all four output writers are enabled by default. Disable defaults only when building a deliberately smaller library.
readstat-rs is licensed under the MIT License.
βΉοΈ On Windows the
readstat-iconv-syscrate compiles and statically links the vendored win-iconv, which is placed in the public domain and imposes no obligations β Windows binaries are MIT like everything else. Linux and macOS builds use the system iconv.
The following have been incredibly helpful while developing!
- How to not RiiR
- Making a *-sys crate
- Rust Closures in FFI
- Rust FFI: Microsoft Flight Simulator SDK
- Stack Overflow answers by Jake Goulding
- ReadStat pull request to add MSVC/Windows support
- jamovi-readstat appveyor.yml file to build ReadStat on Windows
- Arrow documentation for utilizing ArrayBuilders
