Skip to content
CAI
Software that uses CAICheck a score

rusterlium/rustler

62.8

Adequate · 30 September 2026

26.1k

lines of production code

Rust

with C

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is Rustler, a library and toolchain that enables Elixir applications to integrate with Rust via Native Implemented Functions (NIFs). It provides the core Rust bindings, a code generator for creating type-safe interfaces, and Mix tasks to scaffold and compile Rust crates alongside Elixir projects. The system supports various data serialization patterns, including custom structs and JSON via Serde, while offering comprehensive benchmarking and testing infrastructure to ensure performance and correctness.

How it got here

2015–2016 — Project initialization and mix task development

9 changes.

The repository was initialized with a modern Cargo-based workspace structure, replacing legacy C-based build systems and raw bindings. Significant work focused on developing the rustler\_mix package, introducing compile-time configuration macros and scaffolding templates that utilize Rust 2021 and modern Rustler syntax.

2017–2019 — Project scaffolding and test infrastructure

6 changes.

This period focused on establishing developer tooling and comprehensive verification for Rustler. Key work included introducing a Mix task to generate new projects and implementing a code generator for Erlang NIF bindings. Additionally, a modular test suite was built to validate NIF functionality across a wide range of data types and edge cases.

2020–2026 — Benchmarking and serialization support

9 changes.

This period focused on expanding Rustler's capabilities by adding support for building Rust binaries alongside NIF libraries and introducing comprehensive benchmarking infrastructure for performance comparison. Significant effort was also directed toward enhancing test coverage, particularly for BigInt arithmetic, compile-time lifetime handling, and dynamic loading, while integrating a new serde-based serialization test suite with JSON encoding and decoding capabilities.

Features

Add NifRecord benchmark to compare against NifStruct

The benchmarking infrastructure in \rustler\_benchmarks/native/benchmark\ now includes a new \nif\_record\ module that defines a \MyRecord\ struct (tagged "my\_record") with 26 integer fields. This allows users to benchmark the performance of NifRecord encoding/decoding against the existing NifStruct implementation, alongside other miscellaneous term benchmarks provided in \nif\_various\.

_rustler\benchmarks/native/benchmark · high confidence

Add project scaffolding and integration test for rustler\_mix

The rustler\_mix package now includes a .formatter.exs for consistent code formatting, a .gitignore to exclude build artifacts, and an updated README.md that documents installation and usage with the :rustler dependency. Additionally, a test.sh script has been added to verify that the mix task correctly generates a working NIF project, compiles it, and ensures the generated code functions correctly in both development and release environments.

_rustler\mix · high confidence

Added JSON serialization benchmarks for serde\_rustler

A new benchmark suite has been added to the \rustler\_tests/benchmarks\ directory to evaluate the performance of \serde\_rustler\ against other Elixir JSON libraries. The \serde.exs\ script uses Benchee to measure encode, decode, and transcode speeds for libraries including Poison, Jason, JSX, Tiny, jsone, jiffy, and JSON, providing users with comparative performance data.

_rustler\tests/benchmarks · high confidence

Added Rustler benchmarking infrastructure

A new \rustler\_benchmarks\ project has been added to provide performance comparisons for Rustler features. It includes benchmarks for NifStruct and NifRecord decoding/encoding, as well as various other NIF operations like atom handling and term decoding. The benchmarks are compiled in release mode and can be executed via \mix run\ to compare performance metrics.

_rustler\benchmarks · high confidence

Added binary\_example native crate

A new Rust binary example has been added to the rustler\_tests suite. This crate serves as a basic demonstration of a native Rust application, currently printing a simple message to the console upon execution.

_rustler\_tests/native/binary\example · high confidence

Initial import of serde\_rustler test suite

Added the \serde\_rustler\ test module to \rustler\_tests\, introducing Elixir wrappers for NIF-based serialization and deserialization tests. This includes JSON encoding/decoding functions, a \readme\ example demonstrating round-tripping of an \Animal\ struct using NIF-defined type hints, and a \transcode\ function for transcoding via \serde-transcode\.

_rustler\tests/lib/serde · high confidence

Initial project structure and license files

The repository is initialized with the standard project scaffolding for Rustler, including the Apache-2.0 and MIT dual licenses, a comprehensive .gitignore, a .formatter.exs configuration for Elixir subdirectories, and documentation files (README, CHANGELOG, UPGRADE). This commit also removes the legacy C-based build system (Makefile, nifconf\_gen.c) and the initial raw Rust API bindings (erlnif.rs, nif\_init.rs), signaling a shift toward a modern Cargo-based workspace structure.

(repo-wide) · high confidence

Introduce Rustler compile-time configuration macro

Adds the \Rustler\ module, providing a \use Rustler\ macro that enables compile-time configuration for NIF modules. Users can now specify options such as \:otp\_app\, \:crate\, \:load\_data\, and \:load\_data\_fun\ to control how the Rust crate is compiled and how the NIF library is loaded at runtime, including support for dynamic load data generation via a function tuple.

_rustler\mix/lib · high confidence

New OTP header code generator for Rustler NIF bindings

The rustler crate now includes a code generator (\otp\_headers/codegen\) that parses Erlang NIF C headers and produces Rust bindings. This tool supports two emission modes: a 'Main' mode that generates a callback table filled at runtime (e.g., via \dlsym\), and a 'Direct' mode that links directly against NIF API symbols. The generator handles API signature fixes, variadic functions, and type rendering, enabling more robust and maintainable integration with the Erlang/OTP NIF interface.

rustler · high confidence

New \`mix rustler.new\` task for generating Rustler projects

Adds the \mix rustler.new\ Mix task, which generates boilerplate for a new Rustler project. Users can now create a project by running \mix rustler.new\, optionally specifying the Elixir module name, Rust crate name, and OTP application via command-line flags (\--module\, \--name\, \--otp-app\). The task generates the necessary Elixir and Rust files, including a \Cargo.toml\ and \src/lib.rs\, and automatically updates the \.gitignore\ file to exclude the \target/\ directory if it does not already exist.

_rustler\mix/lib/mix · high confidence

Support for building Rust binaries alongside NIF libraries

Rustler now supports compiling and packaging Rust binaries (executables) in addition to NIF libraries. The compiler logic has been refactored to parse Cargo's JSON output for both \:lib\ and \:bin\ artifact kinds, automatically copying generated executables to the project's \priv\ directory alongside shared libraries. This allows projects to distribute compiled Rust tools or utilities with their Erlang/Elixir applications.

_rustler\mix/lib/rustler · high confidence

Architecture

Rustler codegen restructured around a shared Context and template system

The \rustler\_codegen\ crate has been refactored to use a centralized \Context\ struct for parsing derive inputs and a shared \encode\_decode\_templates\ module for generating \Encoder\ and \Decoder\ implementations. This change standardizes how all derive macros (such as \NifStruct\, \NifMap\, \NifRecord\, \NifTuple\, and \NifTaggedEnum\) generate code, ensuring consistent handling of lifetimes, generic type parameters, and atom module naming across the library.

_rustler\codegen · high confidence

Behavioural changes

Refactored compiler configuration and error handling

The compiler logic has been restructured to use a dedicated configuration struct (Rustler.Compiler.Config) that centralizes build settings such as cargo path, features, and environment variables, while replacing the previous TOML-based metadata retrieval with direct cargo metadata calls. Additionally, a new error messaging module (Rustler.Compiler.Messages) provides specific, user-friendly diagnostics for common build failures, including missing rustup, unsupported Rustler versions, and missing build artifacts.

_rustler\mix/lib/rustler/compiler · high confidence

Updated \`mix rustler.new\` templates to use Rust 2021 and workspace structure

The templates generated by \mix rustler.new\ have been updated to use the Rust 2021 edition and a Cargo workspace structure. New projects now include a root \Cargo.toml\ defining a workspace that points to a \native/\<library\_name\>\ directory, and the library template itself targets the 2021 edition. Additionally, the generated README documentation has been refreshed to reflect these structural changes and uses \:erlang.nif\_error/1\ for the placeholder NIF implementation.

_rustler\mix/priv · high confidence

Updated basic NIF template to use modern Rustler syntax

The basic NIF template has been updated to use the modern \\#\[rustler::nif\]\ attribute macro and the \rustler::init!\ macro, replacing older procedural macro patterns. This change ensures that new projects generated from this template adhere to current Rustler conventions and syntax requirements.

_rustler\mix/priv/templates/basic · high confidence

Test coverage

Add Elixir test wrapper modules for Rustler NIFs; Add Rustler NIF tests for BigInt arithmetic; Add dynamic load test for NIF initialization; Add serde\_rustler NIF test suite with JSON encoding/decoding; Added compile-time tests for Rustler NIF type lifetimes; Added test helper for Rustler Mix; Initial test suite for Rustler NIFs; Introduce Rustler test suite with comprehensive NIF coverage.

Dependencies

Rustler 0.38.0 release with Rust 1.91 MSRV and syn 3.0 upgrade

This update introduces Rustler version 0.38.0, raising the Minimum Supported Rust Version (MSRV) to 1.91 and upgrading the \syn\ dependency to version 3.0. The release also adds support for Erlang/OTP 29 via the new \nif\_version\_2\_18\ feature flag, updates the \rustler\_codegen\ proc-macro crate to match the main library version, and configures the workspace to use the Cargo v2 resolver.

(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 68 → 63 (-4.8)
  • Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 96 → 96 (-0.0)
  • Architecture 100 → 83 (-16.8)
  • Maturity 53 → 53 (-0.1)
  • Readiness 84 → 62 (-22.1)
  • Security 67 → 74 (+6.6)

Resolved (4)

  • Documentation: no architecture or design documentation (README.md)
  • Duplicated block (8 lines × 2) (rustler/src/types/map.rs)
  • Duplicated block (9 lines × 2) (rustler/src/wrapper/list.rs)
  • Off-boarding risk: anonymized user #1

New (9)

  • Ambiguous distinction between 'from', 'existing', and 'try' variants. In Erlang NIFs, 'existing' atoms are looked up in the atom table without creating new ones, while 'from' typically creates or looks up. 'try' is often a synonym for 'from' or 'existing' depending on implementation, but here all three exist with similar signatures. This forces users to guess the exact semantic difference (creation vs lookup vs error handling) without clear documentation cues in the signature.
  • Duplicated block (8 lines × 2) (rustler/src/types/map.rs)
  • Duplicated block (9 lines × 2) (rustler/src/types/list.rs)
  • Inconsistent ownership transfer semantics. OwnedBinary::from_raw takes ownership of raw data (likely transferring responsibility to Rust). Binary::from_owned takes an OwnedBinary and an Env, suggesting it might be copying or referencing the data in the environment. The naming from_owned is vague: does it consume the owned binary? Does it create a new owned binary? The relationship between OwnedBinary and Binary (which seems to be a borrowed or environment-bound view) is not clearly reflected in the method names.
  • Naming inconsistency in safety semantics. binary_to_term returns a String, implying it decodes binary data as UTF-8 text. However, the method name binary_to_term in Erlang NIFs usually refers to enif_binary_to_term, which decodes an Erlang term from binary data (serialization), not a string. If this is indeed decoding a serialized term, the return type String is misleading. If it is decoding a binary as a string, the name should be binary_to_string. The _trusted variant suggests a safety distinction, but the base name is confusing.
  • Off-boarding risk: anonymized user #1
  • Projects may be oversized for their cohesion
  • Redundant or unclear distinction between from_term and from_iolist. In Erlang, binaries and iolists are distinct but related. from_term likely expects a binary term, while from_iolist expects an iolist term. However, from_term is a generic name that could imply it handles any term (including iolists) or just binaries. If from_term only accepts binaries, it should be named from_binary_term to be explicit. If it accepts iolists, from_iolist is redundant.
  • Same ambiguity as from_bytes. The presence of try_from_str alongside from_str and existing_from_str creates a tripartite naming scheme that is likely redundant or confusing. try_from usually implies a fallible conversion that might return None or an Err, whereas from might panic or return a specific error atom. The distinction between from and try is not immediately obvious from the signature alone.

Changes since last survey

  • 7 commits — 7 feature/other, 0 fixes

By area

  • rustler/src — 3 commits
  • (repo) — 2 commits
  • rustler_codegen/Cargo.toml — 1 commit
  • rustler_tests/native — 1 commit

Notable commits

  • change: Drop rustler::wrapper (#768)
  • change: Drop unnecessary type aliases
  • change: Drop unused dependency from rustler_codegen
  • change: Merge pull request #766 from filmor/term-newtype
  • change: Merge pull request #767 from rusterlium/nightly
  • change: Nightly Rust warns on non-kebap-case binary names
  • change: The min_value()/max_value() functions are replaced in favour of MIN/MAX

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

Survey your own repository

rusterlium/rustler 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 c42d64cd63cdc9c4acd5b28e8cc1fe51e7be3949 — 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.