Write eBPF programs in Go. Compile with TinyGo. Run in the Linux kernel.
Status: Experimental 0.x project, solo-maintained. Expect breaking changes to the CLI, config schema, public API, and generated code between minor versions. Pin a specific version if you depend on it.
eBPF lets sandboxed programs run inside the Linux kernel -- but today those programs must be written in C or Rust, even when the rest of your stack is Go.
tinybpf lets you write both the kernel-side BPF program and the userspace loader in Go. No C, no CGo, no bpf2go code generation from C sources. One language, one toolchain.
graph LR
A["Go source"] --> B["TinyGo"]
B --> C["LLVM IR"]
C --> D["tinybpf"]
D --> E["bpf.o"]
E --> F["tinybpf generate"]
F --> G["typed Go loader"]
The output is a standard BPF ELF object compatible with cilium/ebpf, libbpf, and bpftool. tinybpf generate then reads that object and produces type-safe Go structs for loading it -- no string-based map lookups, no unsafe.Pointer casts.
# Scaffold, build, and generate a typed loader
tinybpf init my_probe && cd my_probe
make build
make generateWrite your BPF program in Go:
//go:build tinygo
package main
import "unsafe"
//go:extern bpf_get_current_pid_tgid
func bpfGetCurrentPidTgid() uint64
//export my_probe
func my_probe(ctx unsafe.Pointer) int32 {
_ = bpfGetCurrentPidTgid()
return 0
}
func main() {}Load and attach with the generated typed structs:
// Generated by tinybpf generate -- type-safe, no string lookups
objs, err := loader.Load("build/my_probe.bpf.o")
defer objs.Close()
// objs.MyProbe is a *ebpf.Program -- use it directly with cilium/ebpf
kp, err := link.Kprobe("do_sys_openat2", objs.MyProbe, nil)| Dependency | Version | Required |
|---|---|---|
| Go | 1.24+ | Yes |
| TinyGo | 0.40+ | Yes |
LLVM (llvm-link, opt, llc) |
20+ | Yes |
llvm-ar, llvm-objcopy |
20+ | For .a / .o inputs |
pahole |
For BTF injection |
Or install everything at once:
make setup # install all dependencies
make doctor # verify toolchainSee Getting Started for toolchain install details.
| Example | Hook type | What it demonstrates |
|---|---|---|
| tracepoint-connect | Tracepoint | Ring buffer, event capture, cilium/ebpf loader |
| kprobe-openat | Kprobe | Function tracing, pt_regs context |
| fentry-open | Fentry | BTF-based tracing (kernel 5.5+) |
| rawtp-sched | Raw tracepoint | CO-RE portable structs, perf event array |
| percpu-counter | Tracepoint | Per-CPU array map, lock-free counting |
| Example | Hook type | What it demonstrates |
|---|---|---|
| cgroup-connect | Cgroup | Hash map blocklist, connection policy |
| xdp-filter | XDP | Packet parsing, source IP blocklist |
| tc-filter | TC classifier | Port-based packet filtering |
| Example | Hook type | What it demonstrates |
|---|---|---|
| lsm-file-open | LSM | Security audit hook, file open monitoring |
| Example | Hook type | What it demonstrates |
|---|---|---|
| kfunc-task | Fentry | bpf_task_from_pid + bpf_task_release, BTF-resolved kernel functions |
Build and run any example:
make example NAME=tracepoint-connect
sudo ./examples/tracepoint-connect/scripts/run.shEach example has its own README with attach/run details.
Use tinybpf as a Go library to compile BPF objects programmatically:
result, err := tinybpf.Build(context.Background(), tinybpf.Request{
Package: "./bpf",
Output: "probe.bpf.o",
})See the Request documentation for all options.
| tinybpf | bpf2go (cilium/ebpf) | Aya (Rust) | |
|---|---|---|---|
| BPF program language | Go | C | Rust |
| Loader language | Go | Go | Rust |
| CGo dependency | No | No | No |
| Type-safe loader codegen | Yes | Yes | Yes |
| Loader library | cilium/ebpf | cilium/ebpf | aya |
tinybpf is for teams that want to write eBPF in Go instead of maintaining a C/Go split. If your stack is already Go, you no longer need C for the kernel side.
| Document | Description |
|---|---|
| Getting Started | Toolchain prerequisites and install |
| Writing Go for eBPF | Language constraints, helpers, CO-RE, kfuncs |
| CLI Reference | Every command, flag, and default |
| Config Reference | tinybpf.json schema and merge rules |
| Troubleshooting | Setup issues, pipeline errors, verifier debugging |
| Architecture | Pipeline design and the 8-pass IR transformation |
| Project Layout | Package map |
| Support Matrix | Tested toolchain versions and platforms |