getrandom is the thin layer where Rust asks the operating system for entropy
A small cross-platform library for retrieving random data from (operating) system source
At a glance
- What is it?
- getrandom is a small Rust crate that retrieves random data from operating system sources, with a per-target backend table covering Linux, Windows, Apple platforms, the BSDs, Fuchsia, Haiku, WASI and a dozen embedded and exotic targets. It is explicitly a low-level API, and the crate carries a set of opt-in backends that let you bypass the defaults with a cfg flag, which is both its power and its sharpest edge.
- Who is it for?
- Adopt getrandom directly if you are writing a low-level crate that must not pull in rand, and you need to reason about which operating system call backs the entropy on each target you support. Do not adopt it as an application level random number generator, because the README says most users should prefer a higher-level library like rand, and the API here is a raw byte fill with no distribution, no seeding and no ergonomics.
- 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 2 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 October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One function, and the assumption underneath it
getrandom is a Rust library for retrieving random data from operating system sources. The README states the assumption it makes: the system always provides high-quality, cryptographically secure random data, ideally backed by hardware entropy sources. There is no seeding, no user supplied entropy, and no fallback to a userland generator, because the library does not believe it should have one.
The API is one function. The example in the README fills a buffer:
fn get_random_u128() -> Result<u128, getrandom::Error> {
let mut buf = [0u8; 16];
getrandom::fill(&mut buf)?;
Ok(u128::from_ne_bytes(buf))
}That is the whole surface. You ask for bytes, you get bytes, and the error type is the crate's own. The naming comes from the Linux getrandom syscall, but the crate is cross-platform, roughly supporting the same set of platforms as Rust's std library.
The README is direct about the audience. This is a low-level API, and most users should prefer using a higher-level random-number library like rand. That sentence is the correct starting point for any evaluation. getrandom is the layer underneath, not the layer you build an application on.
The crate metadata reflects that positioning. The categories are os and no-std, the description says it is a small cross-platform library for retrieving random data from system source, and the documentation points at docs.rs/getrandom. The version is 0.4.3 on edition 2024 with rust-version 1.85.
A backend per operating system, listed in a table you can read in a minute
The supported targets table is the most informative part of the README, because it shows that the crate is not a thin syscall wrapper but a portability layer with a decision for every platform it knows about.
On Linux and Android, the implementation is the getrandom system call if available, otherwise /dev/urandom after successfully polling /dev/random. That fallback chain matters, because the ordering is a security decision rather than a convenience: the syscall is preferred, and the device file is only used after the kernel's own entropy pool has been polled successfully.
The Apple platforms split by version. macOS uses getentropy, while iOS, tvOS and watchOS use CCRandomGenerateBytes. Windows splits too, with Windows 10 and later using ProcessPrng and Windows 7 and 8 using RtlGenRandom.
The BSD family is mostly syscall based. FreeBSD and Dragonfly BSD use getrandom, OpenBSD uses getentropy, and NetBSD uses getrandom if available and otherwise kern.arandom. Solaris and illumos use getrandom with GRND_RANDOM, Fuchsia uses cprng_draw, and Redox, Haiku, QNX Neutrino and AIX all fall back to /dev/urandom, with the README noting that for Haiku and QNX this device is identical to /dev/random.
Then there are the targets most libraries never think about. Hermit uses sys_read_entropy, SGX and Motor OS use RDRAND, VxWorks uses randABytes after checking entropy pool initialisation with randSecure, and the Nintendo 3DS, PS Vita, SOLID and Emscripten rows each name their own mechanism. Pull requests that add support for new targets are described as always welcome.
WebAssembly is supported for WASI and deliberately not for wasm-pack
The WebAssembly section is the part of the README that reads like a warning notice, and it is worth reading in full before you build anything for the browser.
The crate fully supports the WASI and Emscripten targets, with random_get for WASI 0.1 and get-random-u64 for WASI 0.2. But the wasm32-unknown-unknown and wasm64-unknown-unknown targets, which is the target used by wasm-pack, are not automatically supported. The reason is stated plainly: from the target name alone, the crate cannot deduce which JavaScript interface should be used, or if JavaScript is available at all.
So support is opt in through the wasm_js crate feature, which uses Crypto.getRandomValues via wasm-bindgen. The README then explains why this is not in the default configuration: the JS backend, which supports web browsers, web workers and Node.js v19 or later, requires wasm-bindgen, which bloats Cargo.lock and potentially breaks builds on non-web WASM platforms.
The warning is about libraries rather than applications. The README strongly recommends against enabling this feature in libraries, except for tests, since it is known to break non-Web WASM builds, and since the usage of wasm-bindgen causes significant bloat to Cargo.lock on all targets.
There is one exception to the exception. If your crate already unconditionally depends on wasm-bindgen or js-sys on unknown WASM targets, then it is acceptable to enable this feature unconditionally. The feature definition in Cargo.toml mirrors the same wording in the comments, and adds that the getrandom_backend cfg may override it, so a project that wants a specific backend on a specific target can still get one.
Opt-in backends are selected by a cfg flag, and misconfiguration is dangerous
Beyond the defaults, getrandom provides optional backends that let you choose where the randomness comes from, selected with the getrandom_backend configuration flag.
The list is long and covers several distinct ideas. linux_getrandom uses the getrandom system call on Linux and Android with no /dev/urandom fallback, which bumps the minimum supported Linux kernel version to 3.17 and the Android API level to 23, Marshmallow. linux_raw does the same thing but uses raw asm-based syscalls instead of libc. rdrand uses the RDRAND instruction on x86 and x86-64, and rndr uses the RNDR register on AArch64. efi_rng uses EFI_RNG_PROTOCOL with EFI_RNG_ALGORITHM_RAW on UEFI targets, which requires std and a nightly compiler. windows_legacy forces RtlGenRandom on Windows even where a newer interface exists.
Three of them are escape hatches rather than platform choices. custom is a user-provided implementation for all targets, and unsupported always returns Err(Error::UNSUPPORTED). extern_impl is an externally provided implementation, and it is the one used to build the published documentation, since the docs.rs metadata passes a rustdoc-arg of the getrandom_backend extern_impl cfg.
The flag can be set per target in .cargo/config.toml, and the README recommends doing it that way:
# It's recommended to set the flag on a per-target basis:
[target.'cfg(target_os = "linux")']
rustflags = ['--cfg', 'getrandom_backend="linux_getrandom"']Or through the RUSTFLAGS environment variable:
RUSTFLAGS='--cfg getrandom_backend="linux_getrandom"' cargo buildThe closing warning is the important part. Enabling an opt-in backend replaces the default one, doing this for an incorrect target, such as using linux_getrandom while compiling for a Windows target, will result in a compilation error, and the README says to be extremely careful because incorrect configuration may result in vulnerable applications or applications that always panic. A cfg flag set in a build environment is invisible in the source, which is why the per-target configuration file is the recommended route.
A small crate with a serious test and tooling footprint
The repository layout shows more care than a crate this small usually has. There is a .cargo/ directory at the root, which is where per-target configuration naturally lives, and a build.rs. There is a src/ directory, a tests/ directory, a benches/ directory, and two directories with unusual names that explain themselves: custom_impl_test/ and nopanic_check/.
Those two are the interesting ones. custom_impl_test is where the custom backend gets exercised, which is the only way to know that a user provided implementation actually plugs in correctly. nopanic_check is there because a random number generator that can panic in its error path is a security problem, and a check that fails the build if a panic path is introduced into the no-panic code region is the way to keep that guarantee.
The feature table in Cargo.toml is also commented in a way that reveals intent. The std feature implements From<getrandom::Error> for std::io::Error and uses std to retrieve operating system error descriptions, so without it you get a less informative error type. The sys_rng feature provides SysRng over rand_core, which is the bridge that lets a higher-level library consume this one, and the rand_core dependency is optional and only pulled in with that flag.
The dependency list is short. cfg-if is the only unconditional dependency, and rand_core is optional. The version is 0.4.3, edition 2024, rust-version 1.85, and the licence is MIT OR Apache-2.0, with LICENSE-APACHE and LICENSE-MIT both at the repository root, the standard dual licensing for a crate in that ecosystem. The authors field credits the Rand Project Developers.
The maintenance record is current: the last push was on 2026-10-20 and the repository is not archived. The repository has no GitHub releases, so the crates.io version is the reference point, and there is a CHANGELOG.md, a SECURITY.md and a .typos.toml for the spell checker.
When a higher-level generator is the right call
The limitation is stated in the README itself: most users should prefer using a higher-level random-number library like rand. That is not a hedge, it is a description of the API's altitude.
getrandom::fill takes a byte buffer and gives you bytes. It has no notion of a uniform distribution, no seeding, no thread-local state, no splitting, and no API for generating a number in a range. Every one of those conveniences is a layer you would add yourself, which is precisely what the rand crate and its family exist to provide.
So the wrong-tool case is the ordinary application case. If you are writing a game, a simulation, a Monte Carlo sampler or a load generator, a higher-level crate gives you a uniform distribution over a range in one call, and the difference in your code size is large.
The right-tool case is narrower and clearer. If you are writing a low-level crate, a cryptographic implementation, a key generation routine or a networking library, and you need entropy without taking on a dependency tree and a seeding model you did not ask for, then getrandom is exactly the right size of component. Its dependency footprint of a single unconditional crate is a genuine advantage in that position, and the sys_rng feature exists so that a higher-level library can adopt it without giving up its own API.
The other wrong-tool case is the opt-in backend. If your plan is to select a specific entropy source per target, you are taking on configuration that is invisible in the source tree and that the README explicitly warns can produce vulnerable applications or applications that always panic. The defaults exist, and they are the safer starting point.
Editorial conclusion
Adopt getrandom directly if you are writing a low-level crate that must not pull in rand, and you need to reason about which operating system call backs the entropy on each target you support. Do not adopt it as an application level random number generator, because the README says most users should prefer a higher-level library like rand, and the API here is a raw byte fill with no distribution, no seeding and no ergonomics. Verify first which backend your target resolves to by default, whether your Linux kernel and Android API level meet the minimum for the backends you intend to opt into, and that no cfg flag is set in your build environment, since the README warns that an incorrect backend configuration may result in vulnerable applications or applications that always panic.
Frequently asked questions
What does the getrandom crate do?
It is a Rust library for retrieving random data from operating system sources, with the assumption that the system provides high-quality, cryptographically secure data backed by hardware entropy. The API is a single fill function that writes random bytes into a buffer, and the crate is cross-platform.
Which operating system APIs does getrandom use?
It depends on the target. Linux and Android use the getrandom syscall when available and otherwise /dev/urandom after polling /dev/random, macOS uses getentropy, iOS, tvOS and watchOS use CCRandomGenerateBytes, Windows 10 and later use ProcessPrng while Windows 7 and 8 use RtlGenRandom, and there are dedicated implementations for the BSDs, Fuchsia, Haiku, WASI, Emscripten and a range of embedded targets.
How do I enable a getrandom opt-in backend?
Use the getrandom_backend configuration flag, either in the rustflags field of .cargo/config.toml for a specific target, or through the RUSTFLAGS environment variable. The README recommends setting it per target, and warns that an incorrect configuration can cause compilation errors, vulnerable applications or applications that always panic.
Does getrandom work on wasm-pack targets?
Not by default. The wasm32-unknown-unknown and wasm64-unknown-unknown targets are not automatically supported because the target name does not reveal which JavaScript interface applies, and wasm-pack is not available there. The wasm_js crate feature enables Crypto.getRandomValues via wasm-bindgen, and the README strongly recommends against enabling it in libraries since it breaks non-web WASM builds and bloats Cargo.lock.
Should I use getrandom or rand in my Rust project?
The README says getrandom is a low-level API and that most users should prefer a higher-level library like rand. Use getrandom directly when you are building a low-level crate that needs entropy without a seeding model, and use the sys_rng feature if a higher-level library needs to consume it.
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-random-getrandom)Was this useful?