DEV Community

Antonio
Antonio

Posted on

BeeLadybug 0.4.0 — A Blind, Zero-Dependency Overlay for Debugging Anything on Screen

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();
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 attribution field 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' });
Enter fullscreen mode Exit fullscreen mode

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;
  });
Enter fullscreen mode Exit fullscreen mode

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.

GitHub logo 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



https://www.npmjs.com/package/bee-ladybug

Top comments (0)