Capabilities
Yeet is a JavaScript runtime that observes your system from the kernel boundary using a single daemon per machine. No sidecars, no dashboards you have to configure. You write a script, run it, and watch it render live in your terminal. Run it on one host, or deploy it across a fleet and aggregate the results into a hub.
This page walks through what you can build today.
Your first tool
Here's a complete tool that renders a live memory bar. Save it as hot.tsx and run yeet run hot.tsx:
import { Box, Text, signal } from 'yeet:tui';
const pct = signal(0);
yeet.graph.subscribe(
`subscription { meminfo(interval_ms: 1000) { mem_total mem_available } }`,
(resp) => {
const m = (resp.data ?? resp).meminfo;
pct.update(() => ((m.mem_total - m.mem_available) / m.mem_total) * 100);
},
);
const bar = (p, width = 20) => {
const filled = Math.round((p / 100) * width);
return '█'.repeat(filled) + '░'.repeat(width - filled);
};
export default () => (
<Box padding={1} border="round">
<Text>{() => `mem ${bar(pct.get())} ${pct.get().toFixed(0)}%`}</Text>
</Box>
);
That's the whole thing: a subscription to the system graph, a signal that holds the latest value, and a live terminal view that redraws on every sample. Swap meminfo for procs, nvidia, or any other field and you have a different tool. This shape — watch a thing, react, show it — is most of what people build with yeet.
New to writing scripts? See How scripts work for the programming model.
Live system state
Every yeet script talks to the system graph: a single typed interface to live kernel and host telemetry.
The system graph surfaces:
- Processes — every PID: command line, CPU time, resident memory, disk I/O, scheduler run delay, and process state
- CPU — per-core utilization (user, system, iowait, steal, etc.), clock frequencies, and core metadata
- Memory — full
/proc/meminfo: total, free, available, buffers, cached, swap, slab, hugepages, vmalloc - Network — per-interface metadata and live rx/tx counters from
/proc/net/dev - Kernel — context switches, boot time, load averages, running and blocked process counts
- Docker — container list, network membership, Compose metadata, live per-container stats, and streaming logs
- Nvidia GPUs — power draw, temperature, fan speed, utilization, and per-process GPU memory via NVML
- Hardware sensors — temperatures, fan speeds, and voltage readings from any hwmon device under
/sys/class/hwmon
Run yeet graph dump for the full SDL, or yeet graph query '<gql>' to probe any field from the shell.
You subscribe to a query and get successive samples at whatever interval you ask for, so computing rates and deltas is straightforward:
yeet.graph.subscribe(`subscription { kernel_stats { ... } }`, (sample) => {
// runs every interval_ms with fresh data
});
See yeet.graph.subscribe for the full API.
This is the fastest way to get something useful on screen. A process monitor, a live load gauge, a "which container is eating my CPU" panel — all of these are a subscription and a render loop.
eBPF programs and JavaScript
Yeet exposes nearly the entire eBPF map family — including hash maps, LRU maps, LPM tries, per-CPU maps, arrays, and bloom filters — as JavaScript classes. Your script can allocate maps, read and update entries, iterate, and stream events back from the kernel, all without leaving JavaScript and without writing the glue that normally makes eBPF a specialist's job.
Values come back as the shapes you'd expect: 64-bit counters as BigInt, byte buffers as Uint8Array, structs as the object you defined. When the kernel rejects a program, you get the verifier's actual explanation as a JavaScript error, not "load failed."
This is what lets you build stateful tools — connection trackers, traffic samplers, latency histograms — as ordinary programs rather than hand-assembled eBPF pipelines.
Observe inside containers and namespaces
Probes can attach inside arbitrary network and PID namespaces, not just the host. You can target a container by name and observe its workload directly. Combined with the container and cgroup nodes in the system graph, this means a script can scope itself to one container without reinventing target selection each time.
Write tools in TypeScript and JSX
Scripts can be authored in .ts, .tsx, and .jsx. JSX renders natively to yeet's own reactive terminal-UI library — so you lay out a dashboard the same way you'd lay out a web app:
<Box direction="column">
<Text>CPU: {cpu()}%</Text>
<Box direction="row">{/* ... */}</Box>
</Box>
Under the hood it's a from-scratch reactive rendering stack — signals, flexbox-style layout, proper text wrapping — so live-updating, full-screen terminal UIs are the default, not something you build up by hand. If you've written a frontend, you already know how to write a yeet dashboard. See the TUI docs for the full component and JSX reference.
Get paged when something matters
The same callback that updates your dashboard can also alert you. yeet.alert posts to Slack, so a threshold crossing in any subscription becomes a message in a channel — no separate alerting pipeline to stand up. See Alerting for setup and examples.
Run across a fleet
A script that works on one machine runs the same way on many. Deploy it across a fleet and the results aggregate into a hub, so you read one view instead of opening a terminal per box. The same script adapts at runtime to whatever kernel version and architecture it lands on, so a fleet does not have to be uniform.
Each host stays sovereign either way: the daemon is still local to the machine, and no telemetry leaves your systems as a side effect of aggregation.
A fast inner loop
yeet run --watch re-runs your script the moment you save it, surviving crashes and reload errors so a session doesn't die on a typo. And yeet ps / yeet kill let you see and manage running scripts the way you'd manage processes. See Running scripts for the full reference.
What yeet isn't
A few boundaries worth knowing up front:
- No long-term retention. Yeet reads live state and streams events as they happen. It is not a time-series store, and there's no query language over weeks or months of history.
- A narrow sandbox. Scripts get the system graph, eBPF, and the TUI stack — not Node. There's no
fs,fetch,require,node_modules, or bare-specifier imports. The runtime is intentionally small. - Linux only. Yeet observes the Linux kernel. On macOS, development runs inside a Linux VM.
Putting it together
A typical yeet tool is small: subscribe to something in the system graph (or stream events from an eBPF program), react when it crosses a threshold, and render the result to a terminal UI. That shape — watch a thing, react, show it — covers a custom profiler, a container traffic monitor, a live process tree, an alerting widget, and most of what people reach for yeet to build.
Where to go next
- How scripts work — the programming model
- Alerting — page yourself from any subscription
- System graph SDL — run
yeet graph dump