
eBPF is one of the most powerful technologies running inside modern Linux — and one of the most unpleasant to actually write. Before you place a single packet-filtering rule, you split code across two files, fight the verifier’s constraints, hand-wire libbpf map descriptors, generate skeleton headers, and manage a Makefile that ties all of it together. The tools exist. The developer experience does not. KernelScript 0.1, released this week by Multikernel Technologies, is a direct attack on that friction: a type-safe domain-specific language that puts everything — kernel code, user-space code, and map declarations — in a single file, then compiles it to the correct eBPF C output automatically.
The Problem That Actually Needed Solving
Raw eBPF in C is not hard because eBPF itself is complicated. It is hard because the toolchain forces you to think about infrastructure before you can think about your program. A minimal XDP program — one that drops packets above a size threshold — requires a foo.bpf.c kernel-side file with the program logic, a foo.c user-space file to load and attach it, a skeleton header generated from the kernel file, manual map fd wiring between the two sides, and a Makefile that understands the build order. That is the scaffolding cost to say “drop packets bigger than 1400 bytes.”
Cong Wang, founder of Multikernel Technologies and the author of KernelScript, put it plainly at the Linux Foundation Open Source Summit this month: “eBPF is miserable to write.” That framing is either refreshing honesty from a tooling author or a deliberate marketing hook. Either way, it is accurate.
What KernelScript Actually Changes
The core idea is collapsing that scaffolding into a single .ks source file. Functions decorated with @xdp, @tc, @probe, or @perf_event compile to their kernel-side targets. Undecorated functions compile to user-space code. The compiler generates the eBPF C, the loader, and the Makefile — all from one file.
A minimal XDP packet filter in KernelScript looks roughly like this:
var packet_counts: HashMap<u32, u64>;
@xdp
fn packet_filter(ctx: XdpContext) -> XdpAction {
let size = ctx.data_end - ctx.data;
if size > 1400 {
packet_counts[ctx.ingress_ifindex] += 1;
return XDP_DROP;
}
return XDP_PASS;
}
The packet_counts map is a language-level variable — no libbpf map descriptor, no fd lookup, no separate user-space access call. Both sides of the program see it as the same typed variable. This is not just syntax sugar; it eliminates a real class of runtime bugs where kernel-side and user-side map access gets out of sync on type or key.
Where It Fits in the eBPF Tooling Landscape
The realistic options for writing eBPF programs in 2026 are not equivalent:
- bpftrace: Excellent for quick tracing one-liners. Stops being useful when you need full networking programs (XDP/TC) or anything stateful beyond a histogram.
- Rust + Aya: Memory-safe, modern developer experience, actively maintained. Also requires nightly Rust, has CO-RE compatibility issues that caused real-world project switches in 2025, and pulls in a non-trivial toolchain.
- Raw C + libbpf: What Cilium, Falco, and every production eBPF project actually uses. Proven, powerful, verbose, and not going anywhere.
- KernelScript: More expressive than bpftrace, less complex than Rust + Aya. Targets the middle ground — teams that want to write proper XDP/TC programs without the Rust toolchain investment.
The niche is real. Plenty of teams have found bpftrace too limited for networking work but found Rust/Aya’s setup too heavy for a security monitoring script or a custom CNI component. KernelScript is attempting to own that gap. For deeper background on how eBPF works at the kernel level, the eBPF Foundation’s explainer is still the best starting point.
Why the Timing Is Not Accidental
eBPF adoption is no longer a niche concern. CNCF’s Q1 2026 State of Cloud Native report puts production adoption growth at 300% year-over-year. Cilium, the eBPF-based CNI plugin, surpassed Flannel and Calico to become the most widely deployed Kubernetes network plugin — and is now the AWS EKS default. Sixty-seven percent of teams running Kubernetes at scale report using at least one eBPF observability tool. The technology has moved from “interesting kernel trick” to “default infrastructure layer” in roughly three years.
When the underlying platform explodes in adoption, tooling friction that was acceptable becomes a bottleneck. KernelScript is a bet that the next wave of eBPF adopters will not want to learn the full libbpf lifecycle just to write a packet filter.
What You Should Do With This
KernelScript 0.1 is experimental. The GitHub repo says so clearly: syntax, API, and behavior will change without backward compatibility. Do not put this in production. Do not base a new project on it yet.
What you should do is watch it. The single-file model and language-level maps are design ideas worth tracking regardless of whether KernelScript itself survives to 1.0. If you want to try it now — write a simple XDP program and see how far the toolchain takes you — the examples in the repo are a reasonable starting point. The Phoronix writeup from the Open Source Summit covers the technical decisions behind the language in more depth. And Linuxiac’s coverage includes a solid breakdown of the supported program types and map abstractions.
The eBPF ecosystem is growing faster than its developer tooling. KernelScript is one attempt to close that gap. It is early, rough, and worth keeping an eye on.













