This tool works with both Expo and React Native CLI projects. Just install and go.
Images not loading? Loading slow? Stale avatars that never update? Memory ballooning until the app dies? React Native gives you zero visibility into any of it — image HTTP requests never touch the JS network stack, so even network devtools are permanently blind to them.
The Images tool is the visibility layer: every image your app loads — React Native's <Image> and expo-image — appears in a live registry with where it came from (memory cache / disk cache / network), how long it took, how big it decoded, and exactly why it failed. Pure JavaScript — works in Expo Go and release builds.
The tool below is the real thing, running in your browser on a mock storefront screen: watch the loads land, find the 4K hero decoding into a 390pt box, re-encode it on the device for real byte savings, then force a failure and undo it.
Not a video — this is the shipped tool on mock loads. Image HTTP never touches the JS network stack, so network devtools are permanently blind to it.
npm install @buoy-gg/imagesAdd the register import as the first line of your app entry file (index.js / index.ts):
import "@buoy-gg/images/register";
import "@buoy-gg/images/register";
Then the IMAGES tool appears in your floating menu automatically — auto-discovery finds the installed package, no registration needed:
import { FloatingDevTools } from "@buoy-gg/core";
export default function App() {
return (
<>
<YourApp />
<FloatingDevTools />
</>
);
}
import { FloatingDevTools } from "@buoy-gg/core";
export default function App() {
return (
<>
<YourApp />
<FloatingDevTools />
</>
);
}
Why first? RN core's
<Image>instrumentation uses React Native's official component-decorator hook, which must be installed before the Image module first evaluates. expo-image capture has no timing constraint — it works whenever the tool loads. If the import is missing or too late, the tool tells you exactly what to fix instead of sitting silently empty.
Image.queryCache right after loading.onError is captured with the error message; on iOS, RN core also gives you the HTTP status code and response headers.React Native ships an official (if unstable_-prefixed) hook that lets a devtool wrap every <Image> in the app — the Images tool uses it to observe sources and attach load/progress/error handlers app-wide, with zero native code. expo-image's component is instrumented the same way through a render-level patch that's immune to import order. Both paths force-attach the load events the libraries already emit natively, so capture works identically in Expo Go, dev clients, and release builds.
Buoy's own UI (like the thumbnails inside the tool) is excluded from capture — the tool never appears in its own registry.
loaded/total) come from image onProgress events: reliable on iOS RN core and expo-image; RN core on Android (Fresco) doesn't report real byte counts.Image.queryCache, which reflects the cache after the load — combined with whether network progress events fired, the verdict distinguishes a fresh download from a cache hit.width × height × 4 bytes) — the same math the platforms use for RGBA bitmaps.The same live registry streams to Buoy Desktop — the full tool (list, detail, simulations, mass actions) on a big screen — and to your editor's AI agent via the MCP server: get_images audits a screen's images in one call, image_action drives per-image reloads/overrides (including the on-device savings re-encode), and set_image_simulation flips the app-wide modes.
Cache explorer (browse the actual disk cache directories with sizes and ages), per-screen waste reports, and an X-ray overlay mode (badges on every on-screen image).
Image fetches happen in native code (NSURLSession / Fresco), never in the JS network stack — so JS-level network devtools can’t observe them. Buoy Images hooks the image components themselves instead, capturing every load with its cache verdict and timing.
Yes — capture is pure JavaScript (RN’s official component-decorator hook plus an expo-image render patch), so there’s no native module to install and it works in Expo Go, dev clients, and release builds.
The registry compares each image’s decoded pixels against its rendered size × device pixel ratio and totals the estimated wasted decoded bytes — sort by the red verdicts, then use the on-device re-encode to prove what a right-sized source would save.