Aya is an eBPF library for the Rust programming language, built with a focus on developer experience and operability, and it exists so that Rust developers can load, attach, and drive eBPF programs running inside the Linux kernel without depending on C toolchains or C eBPF frameworks.
What it is
Aya is a library for the Rust programming language that handles the user-space side of eBPF, the Linux kernel technology that allows user-supplied programs to run inside the kernel. It is built from the ground up purely in Rust and uses only the libc crate to execute syscalls, which means the Rust program that loads and attaches BPF objects, reads maps, and manages program lifecycle does not link against the two dominant C-based eBPF frameworks.
The concrete thing it replaces is the libbpf and bcc toolchain. Aya does not rely on libbpf nor on bcc, so a project using it does not need a C toolchain, a kernel build, or compiled kernel headers on the build and deployment host. Because it supports the BPF Type Format and links against musl, it offers a compile once, run everywhere solution in which a single self-contained binary can be deployed across many Linux distributions and kernel versions.
Key capabilities
- Support for the BPF Type Format (BTF), transparently enabled when the target kernel supports it, so eBPF programs compiled against one kernel version run on a different kernel version without recompilation.
- Function call relocation and global data maps, which allow eBPF programs to make function calls and to use global variables and initializers.
- Async support with both
tokio and async-std.
- Support for a large chunk of the eBPF API, including
BPF_PROG_TYPE_CGROUP_SKB programs loaded with Ebpf::load_file("ebpf.o") and attached to a cgroup with CgroupSkbAttachType::Ingress and CgroupAttachMode::AllowOverride.
- Fast, dependency-light builds: no kernel build, no compiled headers, and no C toolchain are required, and a release build completes in a matter of seconds.
- Pure Rust implementation built only on the
libc crate, with no libbpf and no bcc underneath.
- Published crate
aya on crates.io, released API documentation at docs.rs/aya, unreleased documentation at docs.aya-rs.dev, and a book at aya-rs.dev/book.
Who uses it and how
- Teams building observability tooling in Rust, matching the project's
observability, bpf, and ebpf topics, where BPF programs are loaded from a Rust service rather than from a Python or C agent.
- Security tooling that hooks kernel execution paths, matching the
security topic; the README's own example attaches an ingress_filter program to the root cgroup so that it is called for all incoming packets, which is cgroup-level packet filtering.
- Operators who distribute one musl-linked static binary to many Linux distributions and kernel versions, avoiding a per-kernel rebuild for each target host.
- Rust applications that already run on
tokio or async-std and want to fold eBPF loading and map access into an existing async runtime.
- Contributors and integrators who meet in the project's Discord channel, use the Awesome Aya project list, and query the Gurubase "Ask Aya Guru" assistant.
Getting started
Add the aya crate from crates.io to a Rust project and load a compiled BPF object, as in Ebpf::load_file("ebpf.o"), then fetch a program by name and attach it; the book at aya-rs.dev/book and the API documentation at docs.rs/aya cover the rest.
How it compares
Aya occupies the same layer as libbpf and bcc, the two projects it explicitly does not rely on, but it approaches that layer from a different direction: it is built from the ground up purely in Rust and depends only on libc for syscalls, where those projects are the established C implementations. That difference is what removes the C toolchain, kernel build, and compiled headers from the build and deployment path.
When to use it — and when not to
Aya is the right pick for Rust teams that want a self-contained binary and a short build with no C toolchain, and it is the wrong pick for shops standardized on bcc or libbpf, on Python eBPF scripting, or on languages other than Rust. A prospective adopter should note that the async support covers tokio and async-std rather than every runtime, that released and unreleased API documentation are split across docs.rs/aya and docs.aya-rs.dev, and that the repository carries 201 open issues alongside 4,811 stars and 477 forks.
project readme (upstream, from github) — read inline


API Documentation

Community

Join the conversation on Discord to discuss anything related to Aya
or discover and contribute to a list of Awesome Aya projects.
Overview
eBPF is a technology that allows running user-supplied programs inside the Linux
kernel. For more info see What is eBPF.
Aya is an eBPF library built with a focus on operability and developer
experience. It does not rely on libbpf nor bcc - it's built from the ground
up purely in Rust, using only the libc crate to execute syscalls. With BTF
support and when linked with musl, it offers a true compile once, run
everywhere solution, where a single self-contained binary can be
deployed on many linux distributions and kernel versions.
Some of the major features provided include:
- Support for the BPF Type Format (BTF), which is transparently enabled when
supported by the target kernel. This allows eBPF programs compiled against
one kernel version to run on different kernel versions without the need to
recompile.
- Support for function call relocation and global data maps, which
allows eBPF programs to make function calls and use global variables
and initializers.
- Async support with both tokio and async-std.
- Easy to deploy and fast to build: aya doesn't require a kernel build or
compiled headers, and not even a C toolchain; a release build completes in a matter
of seconds.
Example
Aya supports a large chunk of the eBPF API. The following example shows how to
use a BPF_PROG_TYPE_CGROUP_SKB program with aya:
use std::fs::File;
use aya::Ebpf;
use aya::programs::{CgroupSkb, CgroupSkbAttachType, CgroupAttachMode};
// load the BPF code
let mut ebpf = Ebpf::load_file("ebpf.o")?;
// get the `ingress_filter` program compiled into `ebpf.o`.
let ingress: &mut CgroupSkb = ebpf.program_mut("ingress_filter")?.try_into()?;
// load the program into the kernel
ingress.load()?;
// attach the program to the root cgroup. `ingress_filter` will be called for all
// incoming packets.
let cgroup = File::open("/sys/fs/cgroup/unified")?;
ingress.attach(cgroup, CgroupSkbAttachType::Ingress, CgroupAttachMode::AllowOverride)?;
Contributing
Please see the contributing guide.
License
Aya is distributed under the terms of either the MIT license or the
Apache License (version 2.0), at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.