npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

node-ebpf

v0.1.0

Published

Node.js bindings for libbpf - load and interact with eBPF programs

Readme

node-ebpf

Node.js bindings for libbpf - load and interact with eBPF programs.

Requirements

  • Linux kernel 5.8+
  • Node.js 20+
  • libbpf-dev (apt install libbpf-dev)
  • clang (for compiling BPF programs)

Installation

npm install node-ebpf

Getting Started

1. Write a BPF Program

Create a simple BPF program in C (e.g., hello.bpf.c):

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 256 * 1024);
} events SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_execve")
int trace_execve(void *ctx) {
    int *e = bpf_ringbuf_reserve(&events, sizeof(int), 0);
    if (e) {
        *e = 42;
        bpf_ringbuf_submit(e, 0);
    }
    return 0;
}

char LICENSE[] SEC("license") = "GPL";

2. Compile the BPF Program

clang -O2 -target bpf -c hello.bpf.c -o hello.bpf.o

3. Load and Attach from Node.js

import { BpfObject, RingBuffer } from 'node-ebpf';

// Open and load the BPF object
const obj = BpfObject.open('./hello.bpf.o');
obj.load();

// Get the program and attach it
const prog = obj.program('trace_execve');
const link = prog.attach();

// Get the ring buffer map and consume events
const eventsMap = obj.map('events');
const rb = RingBuffer.create(eventsMap, (data) => {
  console.log('Event:', data.readInt32LE(0));
});

// Start event-driven polling
rb.start();

// Cleanup on exit
process.on('SIGINT', () => {
  rb.close();
  link.destroy();
  obj.close();
  process.exit();
});

4. Run with Privileges

sudo node hello.ts
# or grant CAP_BPF
sudo setcap cap_bpf,cap_perfmon+ep $(which node)
node hello.ts

API Reference

BpfObject

Represents a compiled BPF object file containing programs and maps.

Static Methods

BpfObject.open(path: string): BpfObject

Open a BPF object from a file path.

  • path - Path to the .o BPF object file
  • Returns - A new BpfObject instance
  • Throws - Error if the file cannot be opened
const obj = BpfObject.open('./program.bpf.o');
BpfObject.openBuffer(buffer: Buffer, name?: string): BpfObject

Open a BPF object from a memory buffer.

  • buffer - Buffer containing the ELF object data
  • name - Optional name for the object (defaults to "buffer")
  • Returns - A new BpfObject instance
const data = fs.readFileSync('./program.bpf.o');
const obj = BpfObject.openBuffer(data, 'my_program');

Instance Methods

load(): void

Load all BPF programs in the object into the kernel. Must be called before attaching programs.

obj.load();
close(): void

Close the BPF object and release all resources. Programs and maps become invalid after this call.

obj.close();
program(name: string): BpfProgram | null

Get a program by its function name.

  • name - The function name defined in the BPF C code
  • Returns - BpfProgram instance or null if not found
const prog = obj.program('trace_execve');
programs(): BpfProgram[]

Get all programs in the object.

for (const prog of obj.programs()) {
  console.log(prog.name, prog.type);
}
map(name: string): BpfMap | null

Get a map by its variable name.

  • name - The map variable name defined in the BPF C code
  • Returns - BpfMap instance or null if not found
const map = obj.map('events');
maps(): BpfMap[]

Get all maps in the object.

for (const map of obj.maps()) {
  console.log(map.name, map.type, map.keySize, map.valueSize);
}

Properties

  • name: string - Object name (usually the filename)
  • isLoaded: boolean - Whether load() has been called

BpfProgram

Represents a BPF program that can be attached to kernel hooks.

Instance Methods

attach(): BpfLink

Auto-attach based on the program's section name (e.g., kprobe/func, tracepoint/...).

const link = prog.attach();
attachKprobe(funcName: string, retprobe?: boolean): BpfLink

Attach to a kernel probe.

  • funcName - Kernel function name (e.g., do_sys_open)
  • retprobe - If true, attach as a return probe (default: false)
const link = prog.attachKprobe('do_sys_open');
const retLink = prog.attachKprobe('do_sys_open', true); // kretprobe
attachTracepoint(category: string, name: string): BpfLink

Attach to a kernel tracepoint.

  • category - Tracepoint category (e.g., syscalls, sched)
  • name - Tracepoint name (e.g., sys_enter_open)
const link = prog.attachTracepoint('syscalls', 'sys_enter_execve');
attachXdp(iface: string | number): BpfLink

Attach as an XDP (eXpress Data Path) program.

  • iface - Network interface name (e.g., eth0) or index
const link = prog.attachXdp('eth0');
attachRawTracepoint(name: string): BpfLink

Attach to a raw tracepoint.

  • name - Raw tracepoint name (e.g., sched_switch)
const link = prog.attachRawTracepoint('sched_switch');
pin(path: string): void

Pin the program to the BPF filesystem.

unpin(path: string): void

Unpin the program from the BPF filesystem.

setAutoload(value: boolean): void

Set whether this program should be auto-loaded.

Properties

  • fd: number - File descriptor of the loaded program
  • name: string - Program function name
  • type: ProgType - Program type (KPROBE, TRACEPOINT, XDP, etc.)
  • sectionName: string - ELF section name
  • autoload: boolean - Auto-load setting

BpfMap

Represents a BPF map for kernel/userspace data sharing.

Instance Methods

lookup(key: Buffer): Buffer | null

Look up a value by key.

  • key - Key buffer (must match keySize bytes)
  • Returns - Value buffer or null if not found
const key = Buffer.alloc(4);
key.writeUInt32LE(123);
const value = map.lookup(key);
update(key: Buffer, value: Buffer, flags?: UpdateFlags): void

Update or insert a key-value pair.

  • key - Key buffer (must match keySize bytes)
  • value - Value buffer (must match valueSize bytes)
  • flags - Update flags: UpdateFlags.ANY (default), NOEXIST, EXIST
const key = Buffer.alloc(4);
const value = Buffer.alloc(8);
key.writeUInt32LE(123);
value.writeBigUInt64LE(456n);
map.update(key, value);
delete(key: Buffer): boolean

Delete an entry by key.

  • key - Key buffer
  • Returns - true if deleted, false if not found
map.delete(key);
getNextKey(key?: Buffer | null): Buffer | null

Get the next key in iteration order.

  • key - Current key, or null/undefined for the first key
  • Returns - Next key or null if at end
keys(): Generator<Buffer>

Iterate over all keys.

for (const key of map.keys()) {
  console.log(key);
}
entries(): Generator<[Buffer, Buffer]>

Iterate over all key-value pairs.

for (const [key, value] of map.entries()) {
  console.log(key, value);
}
values(): Generator<Buffer>

Iterate over all values.

Properties

  • fd: number - File descriptor
  • name: string - Map variable name
  • type: MapType - Map type (HASH, ARRAY, RINGBUF, etc.)
  • keySize: number - Key size in bytes
  • valueSize: number - Value size in bytes
  • maxEntries: number - Maximum number of entries

BpfLink

Represents an attachment of a BPF program to a kernel hook.

Instance Methods

destroy(): void

Destroy the link and detach the program.

link.destroy();
detach(): void

Detach the program but keep the link object.

pin(path: string): void

Pin the link to the BPF filesystem.

unpin(): void

Unpin the link from the BPF filesystem.

Properties

  • fd: number - File descriptor
  • isValid: boolean - Whether the link is still valid

RingBuffer

EventEmitter-based ring buffer consumer for efficient kernel-to-userspace data streaming.

Static Methods

RingBuffer.create(map: BpfMap, callback?: RingBufferCallback): RingBuffer

Create a ring buffer consumer from a BPF map.

  • map - BpfMap of type RINGBUF
  • callback - Optional callback for each data sample
const rb = RingBuffer.create(map, (data) => {
  console.log('Received:', data);
});
RingBuffer.fromFd(mapFd: number, callback?: RingBufferCallback): RingBuffer

Create from a map file descriptor.

Instance Methods

start(): void

Start automatic event-driven polling. Integrates with Node's event loop using libuv.

rb.start();
rb.on('data', (data) => console.log(data));
stop(): void

Stop automatic polling.

poll(timeoutMs?: number): number

Manually poll for new data.

  • timeoutMs - Timeout in ms (0 = non-blocking, -1 = infinite)
  • Returns - Number of samples consumed
consume(): number

Consume all available data without blocking.

close(): void

Close the ring buffer and release resources.

Properties

  • epollFd: number - Epoll file descriptor for custom integration
  • watching: boolean - Whether automatic polling is active
  • closed: boolean - Whether the ring buffer is closed

Events

  • data - Emitted for each data sample (Buffer)
  • error - Emitted on errors

Utility Functions

setLogCallback(callback: LogCallback | null): void

Set the libbpf log callback.

import { setLogCallback } from 'node-ebpf';

setLogCallback((level, msg) => {
  console.log(`[libbpf:${level}] ${msg}`);
});
getLibbpfVersion(): string

Get the libbpf version string.

probeProgType(type: ProgType): boolean

Check if a program type is supported by the kernel.

probeMapType(type: MapType): boolean

Check if a map type is supported by the kernel.


Constants

MapType

import { MapType } from 'node-ebpf';

MapType.HASH          // Hash table
MapType.ARRAY         // Array
MapType.RINGBUF       // Ring buffer
MapType.PERF_EVENT_ARRAY
MapType.PERCPU_HASH
MapType.PERCPU_ARRAY
// ... and more

ProgType

import { ProgType } from 'node-ebpf';

ProgType.KPROBE
ProgType.TRACEPOINT
ProgType.XDP
ProgType.RAW_TRACEPOINT
ProgType.SOCKET_FILTER
// ... and more

UpdateFlags

import { UpdateFlags } from 'node-ebpf';

UpdateFlags.ANY      // Create or update
UpdateFlags.NOEXIST  // Create only if doesn't exist
UpdateFlags.EXIST    // Update only if exists

Examples

See the examples directory for complete working examples.

License

Apache-2.0