ndarray: Rust's n-dimensional array, views first, BLAS optional
ndarray: an N-dimensional array with array views, multidimensional slicing, and efficient operations
At a glance
- What is it?
- ndarray is the rust-ndarray project's crate providing an n-dimensional container for general elements and for numerics, with owned arrays and array views, multidimensional slicing with arbitrary step sizes and negative indices, and efficient floating point matrix multiplication through its own matrixmultiply crate or an optional pluggable BLAS backend. Dual licensed MIT and Apache-2.0, it runs without the standard library when the std feature is disabled, and sits at version 0.17.2.
- Who is it for?
- Use ndarray when Rust code needs numeric arrays with NumPy-shaped ergonomics, views and slicing without copying, and matrix multiplication tuned for large matrices, and pair it with nalgebra instead when small fixed-size linear algebra dominates.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 75 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the crate is, in four highlights
The README compresses the crate into four highlights, generic one through n-dimensional arrays, owned arrays and array views, slicing with arbitrary step size and negative indices meaning elements from the end of the axis, and views and subviews of arrays with iterators that yield subviews. Each bullet encodes an architectural position, the generic element support means an array of anything, not only floats, while the numerics support means the numeric paths get the optimization attention. The view system is the crate's identity, a view is a non-owning window into an array with its own shape and strides, so slicing, transposing and chunking cost no data movement, the property that makes the crate usable on large datasets where copies would dominate runtime. The quickstart tutorial the README links sits beside it as README-quick-start.md, a second readme dedicated to getting a working example on screen, and the crates.io readme is a third trimmed variant, three documents tuned to three audiences, the browser, the learner and the package page.
The name, and the NumPy shadow
ndarray means n-dimensional array, the term NumPy standardized, and the search interest around the crate reflects that shadow, people arriving with Python questions about ndarray objects and finding a Rust crate of the same concept. Within Rust, the word distinguishes the crate from the language's built-in fixed-size arrays, which carry their length in the type and cannot reshape, and from vectors, which are one-dimensional. The crate's own description splits the difference its users need, an n-dimensional array for general elements and for numerics, lightweight array views and slicing, with views supporting chunking and splitting, so the NumPy mental model transfers while the Rust ownership model reshapes how the API expresses views and mutation. The community channels tell the same lineage story, the crate lives in the rust-sci rooms on Matrix and IRC on OFTC, the gathering places of the Rust scientific computing community that formed around projects like this one.
Views, subviews, and the performance guidance
The status section gives explicit performance doctrine, prefer higher order methods and arithmetic operations on arrays first, then iteration, and as a last priority using indexed algorithms. The ordering reflects the crate's internals, whole-array operations can vectorize and optimize across the layout, per-element iteration loses some of that, and indexed access loses bounds-check elimination opportunities the other paths have. The examples directory teaches by pattern names, bounds_check_elim demonstrating the indexed case done right, column_standardize, convo for convolution, rollaxis and axis_ops for the view operations, zip_many for combining arrays, and life, a Game of Life implementation, as the canonical iteration example. Efficient floating point matrix multiplication for very large matrices is called out as a strength, optionally improvable with BLAS. The doctrine also explains the bounds_check_elim example by name, indexed access carries a bounds check per element unless the compiler can prove safety, and the example shows the patterns that let it, the difference between an indexed loop that optimizes and one that silently doubles runtime.
no_std, and what it costs
The std feature is enabled by default, and the crate can be used without the standard library by disabling it, with the exact Cargo.toml dependency line documented, ndarray with default-features set to false. The cost is enumerated precisely, the geomspace, linspace, logspace, range, std, var, var_axis and std_axis methods are only available when std is enabled, so the space generators and variance statistics are the parts that need allocation and floating point formatting the standard library provides. The no_std mode serves embedded and kernel-adjacent Rust, where arrays of sensor data need slicing and arithmetic but not the full standard library, and the further portable-atomic-critical-section feature adjusts how portable-atomic behaves on targets without native atomic support, extending the embedded reach.
The BLAS integration, and who picks the backend
BLAS integration is an optional add-on, and without it the crate uses the matrixmultiply crate for f64 and f32 matrix multiplication, always enabled as a fallback because it supports matrices of arbitrary strides in both dimensions, the generality a BLAS call cannot always assume. Enabling blas brings in cblas-sys, and the integration rule is stated with emphasis, depend and link to blas-src directly to pick a provider, with the backend version required to be the one blas-src depends on. The architectural note matters, only end-user projects, not libraries, should select the provider, since a library forcing openblas on its consumers creates version conflicts downstream. The system openblas example wires three dependencies, ndarray with the blas feature, blas-src with openblas, and openblas-src with the cblas and system features, and the comment adds that system-installed dependencies save a long time building. The gemm feature enabled on matrixmultiply in the manifest adds the complex number generalization of matrix multiply, so even the fallback path covers complex arithmetic before any BLAS is involved.
A compatibility table and the MSRV caveat
The README publishes a verified combinations table for ndarray, blas-src, openblas-src and netlib-src versions, 0.16 with blas-src 0.10 and openblas-src 0.10, 0.15 with two blas-src generations, and older rows back to 0.13, and the note beneath relaxes the constraint, for ndarray 0.15 or later there is no tight coupling to the blas-src version, so version selection is more flexible. The BLAS on MSRV section adds the honest caveat, although ndarray maintains an MSRV through its rust-version field, at 1.87 for the current release, this is separate from the stated or real MSRV of the BLAS providers, so a toolchain the crate accepts may still fail on a backend it pulls in. Publishing both the table and the caveat is the difference between integration docs that work and ones that frustrate. The netlib row completes the matrix, the compiled configuration shown in the README uses blas-src with default features disabled and the netlib feature enabled, and linking follows the same extern crate blas_src requirement, so the two providers differ mainly in build time and provenance rather than integration steps.
Testing depth and the release rhythm
The repository's dev-dependencies reveal the verification style, quickcheck and proptest for property-based testing of the array operations, approx for float comparison, itertools and defmac for test ergonomics, and a proptest-regressions directory persisting the shrinking cases that found bugs, the institutional memory of property testing. Benches, examples, a crates directory holding ndarray-rand for random array generation with its own release tags, and scripts round out the layout. The release history shows steady but unhurried maintenance, 0.17.1 in November 2025, the ndarray-rand 0.16.0 tag days later, and 0.17.2 on 2026-01-10, with the repository pushed 2026-07-18. Authors Ulrik Sverdrup, bluss, and Jim Turner maintain it, dual licensed to be compatible with the Rust project itself.
Editorial conclusion
Use ndarray when Rust code needs numeric arrays with NumPy-shaped ergonomics, views and slicing without copying, and matrix multiplication tuned for large matrices, and pair it with nalgebra instead when small fixed-size linear algebra dominates. Before adopting, read the status section honestly, the crate is still evolving and breaking changes are expected between versions, prefer its higher order methods and arithmetic over indexed algorithms for performance, and if enabling BLAS, follow the compatibility table, depend on blas-src directly, and let only end-user projects select the provider, with extern crate blas_src linking the backend into the binary.
Frequently asked questions
what is ndarray in Rust?
ndarray is a Rust crate providing an n-dimensional container for general elements and for numerics, with owned arrays and non-owning array views, multidimensional slicing with arbitrary step sizes and negative indices, and efficient matrix multiplication for large floating point matrices, optionally accelerated through a pluggable BLAS backend.
how to use ndarray?
Add the crate to your project with cargo add ndarray, then build arrays and work through the higher order methods and arithmetic operations first, iteration second, and indexed algorithms last, per the crate's own performance guidance. The examples directory demonstrates view operations, bounds-check elimination, convolution and more, and the quickstart tutorial lives beside the README.
What is the difference between ndarray and array?
In Rust, the built-in array type is fixed-size with its length in the type, while the ndarray crate provides dynamically shaped, n-dimensional arrays with views, slicing and numeric operations. The crate's name refers to the n-dimensional array concept, and its views support chunking, splitting and stride tricks that fixed-size arrays cannot express.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rust-ndarray-ndarray)