https://beeenginejs.com/wp-content/uploads/2026/09/Screenshot-2026-09-15-194620.png
The problem I kept running into
Every time I built a new game or a new page, I ended up writing the same throwaway debug code: an FPS counter here, a console.log there, a red box drawn around whatever DOM node I was hunting down. It always lived inside the project it was debugging — which meant it broke, or had to be rewritten, the moment I moved to a different project.
So I pulled it out into its own package: BeeLadybug. The core idea is simple and it's the one rule I refuse to break:
The Core is blind. It doesn't know what a "game," a "DOM node," or a "Python process" is. It only knows
sendData(type, payload).
Everything that actually understands what it's looking at lives in an Adapter. The Core just stores packets, runs a shared clock, and draws an overlay.
Why "blind" matters
The first version of this tool wasn't blind — it was welded to one specific game engine I was building. The moment I wanted to use it on a plain website, I had to rip out half the code. That coupling is exactly what BeeLadybug was built to avoid. A Core that knows nothing about its subject can sit in front of a <canvas> game, a DOM-heavy site, or a Python backend without a single line of the Core itself changing.
The adapters
Four ship today, each one translating a different world into the same generic packets:
import { BeeLadybugCore, CanvasAdapter, WebDOMAdapter } from 'bee-ladybug';
const bee = new BeeLadybugCore();
// Watching a game's canvas
const canvasAdapter = new CanvasAdapter(bee, { canvas: myCanvas });
canvasAdapter.attach();
// Watching a page's DOM
const domAdapter = new WebDOMAdapter(bee, {
root: document.body,
watch: ['.card', 'header', 'footer']
});
domAdapter.attach();
https://beeenginejs.com/wp-content/uploads/2026/09/Immagine-2026-09-15-194536.png
There's also a PythonBridge, which streams telemetry over WebSocket from a Python process — useful if you're inspecting a bot or a simulation running server-side, not just the browser.
What's new in 0.4.0: two purely passive diagnostic modules
The newest additions are two adapters that don't need you to instrument anything by hand — they attach native browser APIs and just watch.
🐜 AntAdapter — DOM mutation rate tracker
It hooks a native MutationObserver and, instead of just logging every change, keeps a 1-second sliding window per node. Cross a mutation-rate threshold (30/sec by default) and it emits a warning naming the offending element:
import { AntAdapter } from 'bee-ladybug';
const ant = new AntAdapter(bee, { root: document.body });
ant.attach();
// → warn: "High Mutation Rate on #cta"
This is the kind of thing that's brutal to notice by eye — some countdown or animation quietly re-rendering way more often than it should — but obvious once something is counting for you.
🕷️ SpiderAdapter — long tasks & slow resources
This one wraps the native PerformanceObserver:
import { SpiderAdapter } from 'bee-ladybug';
const spider = new SpiderAdapter(bee);
spider.attach();
// → telemetry: long task, 85ms
// → warn: slow resource, 640ms
Two honest caveats I'd rather state up front than let you discover the hard way:
- The Long Tasks API (
entryTypes: ['longtask']) is Chromium-only. Firefox and Safari don't expose it, so SpiderAdapter feature-detects and logs once, gracefully, instead of pretending to work everywhere. - Long task entries almost never carry a real script filename — the
attributionfield usually just says"window". Don't expect"caused by game.js"; expect a duration and a rough container type.
Both adapters register themselves through a small generic mechanism I added specifically so the Core would stay blind even as the toolbar grows:
core.registerAdapter('ant', { enable, disable, label: 'ANT' });
The overlay renders one toggle button per registered adapter — it has no hardcoded knowledge that "ANT" or "SPIDER" exist. A future fifth adapter needs zero changes to the overlay code.
Trying it without installing anything
If you just want to see it on a page you don't control the build for, paste this into the browser console:
import('https://cdn.jsdelivr.net/npm/bee-ladybug@0.4.0/src/index.js')
.then(({ BeeLadybugCore, WebDOMAdapter }) => {
const bee = new BeeLadybugCore();
new WebDOMAdapter(bee, { root: document.body }).attach();
window.bee = bee;
});
No build step, no bundler — it's plain ESM, self-contained, zero runtime dependencies.
What's next
Two ideas are on the table but not yet built:
- Motion Trail — a small FIFO buffer of recent (x, y) positions per adapter, drawn with decaying alpha, to visualize movement paths (particularly useful for the Python bridge, where you're watching a remote process's trajectory).
- Persistent Bug Trap — a log of caught errors that survives across page reloads (days, not just the session), so you can catch something intermittent, walk away, and come back to it later. Read-only, no runtime mutation — just a log you clear by hand once you've dealt with it.
If you try BeeLadybug on something of your own, I'd genuinely like to hear where it falls over — that's the fastest way this gets better.
antonioprosperi2-svg
/
BeeLadybug-universal
Lightweight, zero-dependency HUD & telemetry overlay for web apps, game engines, and Python backends. Includes WebSocket bridge and custom AI assistant integration.
BeeLadybug
Universal telemetry and visual inspection overlay.
BeeLadybug is not a Canvas widget. It is a small open-source debugger core that accepts raw packets from any source — Canvas 2D games, DOM pages headless bots, Python processes, AI pipelines — and renders them in one dark console.
Il Core non sa cosa sta monitorando. Riceve solo dati grezzi.
Perché questa struttura
Il file storico BeeLadybug era accoppiato a un engine di gioco (entità,
hitbox, ctx.drawOverlay). Quello non scala a un sito HTML o a un modello
Python. Per questo il progetto riparte da zero con due strati:
Strato
Responsabilità
src/core/
Orologio fittizio, buffer, grafici, overlay cyberpunk
src/adapters/
Traduttori. Convertono un mondo specifico in
sendData()
L'overlay non è disegnato sul Canvas. È un pannello HTML in Shadow DOM: funziona sopra un gioco, sopra una pagina, o da solo in una sandbox.
bee-ladybug/
├── src/
│ ├── index.js # API pubblica…
Top comments (0)