bytemuck

A zero-cost, no_std Rust crate for safely casting between plain data types and reinterpreting slices as bytes.

Library
Cargo
v1.25.2
1,070 stars
Zlib OR Apache-2.0 OR MIT

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
63 /100 Good
Development Activity 52
Maintenance 24
Community 76
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
80 /100 Excellent
Architecture 88
Code Quality 85
Innovation 78
Learning Curve 70

bytemuck lets Rust code perform “bit cast” operations between data types safely, without reaching for unsafe transmutes at every call site. A family of marker traits (Pod, Zeroable, NoUninit, AnyBitPattern, CheckedBitPattern, TransparentWrapper) express exactly which safety guarantees a type upholds, and the crate’s cast/cast_slice functions use those guarantees to reinterpret values and slices as different types without copying.

It is especially popular in Rust’s graphics and game-engine community, where cast_slice is the standard way to turn a slice of vertex/color structs into the raw &[u8] a GPU buffer upload expects. The crate is #![no_std], has effectively no runtime cost, and ships an optional derive feature so consumers can implement the marker traits on their own types with a single attribute instead of writing unsafe impls by hand.

What You Get

  • Five core casting functions — cast, cast_ref, cast_mut, cast_slice, cast_slice_mut — covering owned values, references, and slices
  • A layered trait system (Zeroable, Pod, NoUninit, AnyBitPattern, CheckedBitPattern, TransparentWrapper, Contiguous) so you only claim the safety guarantees your type actually has
  • Fallible try_cast* variants that return a PodCastError instead of panicking on alignment or size mismatches
  • An optional derive feature (via the sibling bytemuck_derive proc-macro crate) that implements the marker traits for your structs and enums with compile-time validation
  • Opt-in feature flags for alloc/std integration, SIMD types (wasm, aarch64, avx512), const-context casting, and more, so the no_std/MSRV-1.34 core stays minimal by default

Common Use Cases

  • Casting a slice of vertex or color structs into &[u8] to upload directly to a GPU buffer
  • Reinterpreting network or file bytes as a fixed-layout struct without manual field-by-field parsing
  • Zero-copy conversion between numeric types and their raw byte representation (e.g. f32 to/from bits)
  • Deriving Pod/Zeroable on #[repr(C)] structs so they can flow through APIs that require plain-old-data types

Under The Hood

Architecture — bytemuck splits its public surface across one file per marker trait: pod.rs defines Pod (the strongest guarantee, valid for any bit pattern and safe under mutable aliasing), zeroable.rs defines the weaker Zeroable, no_uninit.rs and anybitpattern.rs define NoUninit/AnyBitPattern for types that only support a subset of casts, checked.rs layers CheckedBitPattern on top with a runtime validity check (used for C-style enums and similar), transparent.rs defines TransparentWrapper for repr(transparent) newtypes, and contiguous.rs defines Contiguous for enum-to-integer conversions. lib.rs re-exports all of these and implements the actual cast/cast_ref/cast_mut/cast_slice/cast_slice_mut functions on top of core::mem::transmute, guarded by size/alignment assertions in internal.rs. A separate proc-macro crate (derive/, published as bytemuck_derive) implements the #[derive(...)] macros consumed via the optional derive feature, keeping the compile-time-only proc-macro dependency out of the core crate’s default build.

Tech Stack — the core crate is #![no_std] with zero required dependencies, targeting an MSRV of Rust 1.34 for the default feature set. Cargo.toml gates over 30 additional features (derive, extern_crate_alloc/std, zeroable_maybe_uninit, min_const_generics, wasm_simd, aarch64_simd, avx512_simd, const_zeroed, must_cast, and more), each documented with the specific MSRV it requires, so users opt into exactly the surface (and compiler-version cost) they need. The optional derive feature pulls in bytemuck_derive (syn 2, quote, proc-macro2) as a separate proc-macro crate, and nightly_portable_simd optionally depends on rustversion for nightly-only std::simd support.

Code Quality — the tests/ directory has nine dedicated integration test files (cast_slice_tests.rs, checked_tests.rs, array_tests.rs, offset_of_tests.rs, std_tests.rs, transparent.rs, wrapper_forgets.rs, doc_tests.rs, derive.rs) exercising both success and failure paths, including explicit PodCastError variants for misalignment and slop-byte cases. Every unsafe trait (Pod, Zeroable, NoUninit, AnyBitPattern, CheckedBitPattern, TransparentWrapper) carries an extensive doc comment enumerating the exact safety invariants implementers must uphold, and CI is wired through .github/workflows/rust.yml. rustfmt.toml enforces consistent formatting, and the crate’s naming convention (cast_, try_cast_, must_cast_ prefixes) makes fallibility and compile-time-checked variants discoverable from the function name alone.

API Design — the five core functions (cast, cast_ref, cast_mut, cast_slice, cast_slice_mut) map directly onto Rust’s five basic ownership/borrowing forms (T, &T, &mut T, &[T], &mut [T]), which lib.rs’s module-level doc comment states explicitly as the mental model for the whole crate. The derive feature removes almost all boilerplate for common cases — a single #[derive(Pod, Zeroable)] replaces a hand-written unsafe impl block. The trade-off is discoverability: the crate exposes more than 30 Cargo features with subtly different MSRV and safety implications, so newcomers need to read the feature-flag section of lib.rs’s docs closely to pick the right combination for their use case.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers