# portable-simd: the Rust standard library's SIMD API, on nightly

> portable-simd is the crate that will become the Rust standard library's portable SIMD API, and it is usable today behind a feature gate on nightly. The API is small, the vector types are chosen so that one source compiles to several architectures, and the repository doubles as the working group where that API is designed.

**rust-lang/portable-simd** — The testing ground for the future of portable SIMD in Rust

- Repository: https://github.com/rust-lang/portable-simd
- Stars: 1,075 · Forks: 109
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/rust-lang-portable-simd

## A working group, not a finished library

This repository is the code repository for the Portable SIMD Project Group, and the project description calls it the testing ground for the future of portable SIMD in Rust. The README calls it the Rust standard library's portable SIMD API.

Those two framings set the expectations correctly. This is not a stable crate you add to a project, it is where an API is being designed, and the fact that it lives in the rust-lang organisation rather than in a personal repository is the signal. The project group has its own repository at rust-lang/project-portable-simulation, and this one holds the implementation.

A few practical details from the README. The docs for the crate are published from the main branch, so what you read matches the tip. If you have questions about SIMD, a guide has been started at beginners-guide.md in the repository. The team can be found on Zulip in the project-portable-similar stream. And if you are interested in support for a specific architecture, the README points you at stdarch instead, which is the right redirect, because architecture-specific intrinsics are a different project with a different stability story.

The licence is Apache-2.0 in the repository metadata, and the tree carries both LICENSE-APACHE and LICENSE-MIT, so the code is available under either. The last push was on 2026-09-16, the repository is not archived, and there are no GitHub releases.

## Hello world, with a nightly toolchain

The quickstart is the one to copy, and it is short.

Make sure your compiler is up to date and using nightly, which the README does with:

```bash
rustup update -- nightly
```

or by setting up rustup default nightly, or else with cargo +nightly for the build, test and run commands. Then create a crate:

```bash
cargo new hellosimd
```

And write this in src/main.rs:

```rust
#![feature(portable_simd)]
use std::simd::f32x4;
fn main() {
    let a = f32x4::splat(10.0);
    let b = f32x4::from_array([1.0, 2.0, 3.0, 4.0]);
    println!("{:?}", a + b);
}
```

Two things are worth noticing in five lines. The feature gate, portable_simd, is what makes the whole thing possible, and it is the reason the toolchain has to be nightly. And the vector type comes from std::simd, which is the path the standard library will expose, so the import you use today is the one you would use after stabilisation.

The README explains the rest. SIMD vectors are constructed with methods like splat or from_array, and then you can use operators like + on them, and the appropriate SIMD instructions will be carried out. Running cargo run gives [11.0, 12.0, 13.0, 14.0], which is the four-lane addition of the two vectors.

## The vector types, and what is deliberately missing

The supported vectors section defines the surface, and the shape of it is the design.

Currently, vectors may have up to 64 elements, but aliases are provided only up to 512-bit vectors. The number of lanes depends on the primitive type, so 128-bit vectors have four f32 lanes and two f64 lanes.

The supported element types are the primitive types with two exclusions. Floating point is f32 and f64. Signed integers are i8, i16, i32, i64 and isize, with i128 excluded. Unsigned integers are u8, u16, u32, u64 and usize, with u128 excluded. Pointers are supported as *const T and *mut T, with zero-sized metadata only. And the mask types come in 8-bit, 16-bit, 32-bit, 64-bit and usize-sized flavours.

The i128 and u128 exclusions are the kind of detail that tells you the API is being constrained by what the hardware can do rather than by what the language can express. A 128-bit integer vector has no single portable width, so the API declines to promise one.

The masks deserve their own note. They have elements that are truthy values, like bool, but they have an unspecified layout, because different architectures prefer different layouts for mask types. An unspecified layout is a promise that the compiler will pick whichever representation is fastest on the target, and it also means you cannot rely on the size of a mask type in a struct or across an FFI boundary.

Pointers with zero-sized metadata only is the same kind of constraint: a pointer to a slice carries a length, and the portable SIMD API does not attempt to make that work.

## The workspace, and why the test profile is optimised

The Cargo.toml is a three-member workspace, and one line in it is worth understanding.

```toml
[workspace]
resolver = "1"
members = [
    "crates/core_simd",
    "crates/std_float",
    "crates/test_helpers",
]

[profile.test.package."*"]
opt-level = 2
```

The three crates are the core SIMD implementation, a crate for the standard library's floating point handling, and a test helpers crate. The profile line is the interesting one: every package is compiled at optimisation level 2 even in a test build.

That is not a default, and for SIMD it matters. Tests that exercise vector arithmetic at opt-level 0 will measure the scalar fallback rather than the vectorised code, because the compiler does not vectorise at that setting. Testing optimised code is unusual in most projects, and here it is a correctness decision, not just a performance one, since the behaviour under optimisation is the behaviour that will run in production.

The workspace dependencies section adds proptest at 1.11 with the alloc and f16 features, which is the property testing library. Property tests are the right tool for a vector API, because the interesting properties are algebraic, such as an addition being commutative or a splat producing equal lanes, and a property test states them once and checks them across generated inputs rather than asserting a list of examples by hand.

## How the project is wired together

The rest of the repository root shows how a language-level project is put together, and several files have a clear job.

There is a subtree-sync.sh, which is the mechanism for keeping the crates in step with the standard library, where the same code has to exist in more than one tree during the stabilisation process. There is a triagebot.toml, the configuration for the bot that labels and triages incoming issues, which is standard for a rust-lang repository with a steady stream of bug reports. Cross.toml configures cross-compilation, which for a portable SIMD project is not a convenience but the main way to check that the code works on the architectures it claims to support.

There is a rust-toolchain.toml pinning the toolchain, which for a nightly-only crate is the difference between a contributor's build working and not. Cargo.lock is committed, as is usual for a workspace with binaries and examples. beginners-guide.md is the guide the README points at for people with SIMD questions.

The two licence files, LICENSE-APACHE and LICENSE-MIT, are the standard rust-lang dual licence arrangement, and CONTRIBUTING.md is where the contribution guidelines live, which the README asks you to read before opening a pull request. The .github/ directory holds the workflows, and the CI badge at the top of the README points at the ci.yml workflow on the main branch.

The crates/ directory is where the actual code lives, and the top-level entries are the three workspace members. The project is deliberately small in footprint, which is what you would expect from something that is going to become a part of the standard library.

## What to expect from an API that is still moving

The honest caveat about this project is in its own structure. The API is behind a feature gate, the documentation is published from the main branch, and the project has a beginners guide because the usage patterns are not yet obvious to everyone.

For a user, the practical consequences are these. You need a recent nightly, and your build has to allow the feature gate, so a project pinned to a stable toolchain cannot use it. The names and the type list will change before stabilisation, so code written against today's API will need revisiting. And the semantics of a portable vector are not the semantics of an intrinsic, because the width and the instruction set are chosen by the target rather than by you.

That last point is the one to internalise. A portable f32x4 is a fixed four-lane vector, and on a target with a 128-bit vector unit it maps neatly, but the same source on a target with 512-bit registers is still four lanes, which means the compiler has to break the work up or use masking. Performance on a given target is therefore not obvious from the source, and the project group is aware of it, which is part of why the guide is being written at all.

The Rust project's stated direction is that this work ends up in the standard library, and the same repository will then be where the stabilisation tracking happens. For now the value of the repository is twofold: it is the place the API is being shaped, and it is the only way to use the API today.

## Conclusion

Adopt portable-simd if you are writing performance-sensitive Rust and want to express vector work in a way that compiles to several architectures rather than to intrinsics for one. Do not adopt it for production code today without accepting that it is a nightly feature that will change, and do not reach for it when the compiler can vectorise the loop, because a wide vector type is not automatically a fast one. Before you start, update to a recent nightly, and read the beginners guide that the repository ships, since the API is still moving and the guide is the project's own explanation of how it is meant to be used.

## FAQ

### What is the rust-lang/portable-simd repository?

It is the code repository for the Portable SIMD Project Group, described as the testing ground for the future of portable SIMD in Rust, and it holds what will become the Rust standard library's portable SIMD API. The code is available under the Apache or MIT licence.

### How do I try portable SIMD in Rust?

You need a recent nightly, so run rustup update -- nightly, then create a crate with cargo new hellosimd and use a file with #![feature(portable_simd)] and an import of std::simd::f32x4, building with cargo +nightly. Running the example prints [11.0, 12.0, 13.0, 14.0].

### Which vector element types does portable SIMD support?

Floating point f32 and f64, signed integers i8 to i64 plus isize with i128 excluded, unsigned integers u8 to u64 plus usize with u128 excluded, pointers *const T and *mut T with zero-sized metadata only, and masks in 8, 16, 32 and 64-bit plus usize-sized flavours. Vectors may have up to 64 elements, with aliases provided only up to 512-bit vectors.

### Why do the portable SIMD mask types have an unspecified layout?

Because different architectures prefer different layouts for mask types, so the API leaves the choice to the compiler. The mask elements are truthy values like bool, but you cannot rely on the size of a mask type in a struct or across a foreign function boundary.

### How is the portable-simd workspace tested?

The workspace has three members, core_simd, std_float and test_helpers, and every package is compiled at opt-level 2 even in the test profile, so the tests exercise the optimised code rather than the scalar fallback. The workspace also depends on proptest for property testing of the vector operations.

## Sources

- [Issues](https://github.com/rust-lang/portable-simd/issues)
- [License: Apache-2.0](https://github.com/rust-lang/portable-simd/blob/main/LICENSE)
- [README](https://github.com/rust-lang/portable-simd/blob/main/README.md)
- [rust-lang/portable-simd on GitHub](https://github.com/rust-lang/portable-simd)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rust-lang-portable-simd
