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

@yemirhan/android-debugger-ui

v2.0.0

Published

In-app debugger and UI components for React Native apps using Android Debugger

Readme

@yemirhan/android-debugger-ui

An in-app debugger and React Native UI components for apps using @yemirhan/android-debugger-sdk.

  • In-app debugger: a floating button that opens network requests, console output, events and state captured by the SDK, right on the device. It works with or without the desktop app.
  • Hooks to build your own debug screens from the same data.
  • Components: JSON viewer, badges, key/value lists, segmented control, search field and more, all in one dark theme.

Installation

npm install @yemirhan/android-debugger-ui @yemirhan/android-debugger-sdk

Peer dependencies: react, react-native (0.71+), @expo/vector-icons, expo-router and @yemirhan/android-debugger-sdk (2.0+).

In-app debugger

Render DebuggerOverlay once, next to your root navigator:

import { AndroidDebugger } from '@yemirhan/android-debugger-sdk';
import { DebuggerOverlay } from '@yemirhan/android-debugger-ui';

AndroidDebugger.init();

export default function RootLayout() {
  return (
    <>
      <Stack />
      <DebuggerOverlay />
    </>
  );
}

A draggable bug button appears (only in development builds by default). Its dot shows whether the desktop app is connected, and a red badge counts errors (console.error and failed requests) you haven't looked at yet. Tap it to open the debugger:

| Tab | Shows | |-----|-------| | Network | fetch, XMLHttpRequest and intercepted axios requests. Filter by URL, method or status, or show only failed/pending ones. Tap a request for headers and bodies (JSON is shown as a tree), and share it as a cURL command. | | Console | console.* output, colored by level, with level filters and search. Tap a line to inspect logged objects. | | Events | trackEvent() calls, Redux actions and markStart()/markEnd() timings. | | State | The latest snapshot of each store: sendState(), the Redux middleware and interceptZustandStore(). |

The header can clear the current tab and reload the app.

React Native's own requests to Metro (LogBox symbolication) are left out, so they don't bury your app's traffic.

| Prop | Type | Default | Description | |------|------|---------|-------------| | enabled | boolean | __DEV__ | Render nothing when false | | initialTab | 'network' \| 'console' \| 'events' \| 'state' | 'network' | Tab shown when opened |

Embedding the panel

Use DebuggerPanel to put the same debugger in a screen of your own, e.g. a hidden debug menu:

import { DebuggerPanel } from '@yemirhan/android-debugger-ui';

export default function DebugScreen() {
  return <DebuggerPanel initialTab="console" />;
}

| Prop | Type | Description | |------|------|-------------| | initialTab | DebuggerTab | Tab shown first (default 'network') | | onClose | () => void | Shows a close button | | insetTop | number | Extra space above the header |

What gets captured

Data is recorded from the moment this package is imported, so import it early (your root layout). The newest 300 requests, 500 console lines, 300 events and 100 stores are kept. Everything stays on the device, in memory.

Hooks

The debugger is built on these hooks; use them for custom screens. Each re-renders when its data changes (in batches, so a burst of logs causes one render).

import { useNetworkRequests, useDebuggerConnection } from '@yemirhan/android-debugger-ui';

function FailedRequestCount() {
  const requests = useNetworkRequests();
  const connected = useDebuggerConnection();
  const failed = requests.filter((r) => r.error || (r.status ?? 0) >= 400).length;
  return <Text>{failed} failed · desktop {connected ? 'connected' : 'offline'}</Text>;
}

| Hook | Returns | |------|---------| | useDebuggerConnection() | boolean: whether the desktop app is receiving data | | useNetworkRequests() | Requests, oldest first (a request is updated in place when it completes) | | useConsoleLogs() | Console entries, oldest first | | useDebuggerEvents() | Custom events and performance marks, oldest first | | useStateSnapshots() | Latest state per store, most recently updated last | | useDebuggerData() | All of the above in one object |

clearDebuggerData(kind?) forgets one kind ('network', 'console', 'events', 'states') or everything.

Components

All components use the exported theme (colors, radii, spacing, fonts), so custom screens can match.

ConnectionStatus

A badge that shows whether the desktop app is connected. It updates live; pass connected to override.

<ConnectionStatus />

JsonViewer

A collapsible, syntax-colored tree. Large arrays and objects render 100 children at a time.

<JsonViewer data={response} initialExpandDepth={2} />

Badge

<Badge label="GET" mono />
<Badge label="404" tone="warning" mono />
<Badge label="live" tone="success" variant="solid" />

Tones: neutral, accent, success, warning, danger, info.

KeyValueList

<KeyValueList items={[{ key: 'content-type', value: 'application/json' }]} emptyText="No headers" />

SegmentedControl

<SegmentedControl
  value={filter}
  onChange={setFilter}
  options={[
    { value: 'all', label: 'All', count: 12 },
    { value: 'failed', label: 'Failed', count: 2 },
  ]}
/>

SearchField

<SearchField value={query} onChangeText={setQuery} placeholder="Filter by URL" />

Section, EmptyState

<Section title="Response" action={<Badge label="JSON" />}>
  <JsonViewer data={body} />
</Section>

<EmptyState icon="globe-outline" title="No requests yet" description="They show up here as they happen." />

ActionButton

<ActionButton title="Submit" icon="send" variant="primary" loading={false} onPress={submit} />

Variants: primary, secondary, danger.

FeatureCard

A navigation card for expo-router.

<FeatureCard title="Console" description="Log messages, warnings, and errors" icon="terminal" href="/console" />

ResultDisplay

A titled, scrollable list of monospace lines.

<ResultDisplay title="Output" results={['Line 1', 'Line 2']} maxHeight={200} />

Formatting helpers

formatTime, formatDuration, formatBytes, requestState and toCurl are exported for custom screens.

Upgrading from 1.x

  • Requires @yemirhan/android-debugger-sdk 2.0 or later as a peer dependency.
  • ConnectionStatus now shows the live connection state instead of a static "SDK Active" badge.
  • FeatureCard navigates with expo-router's useRouter(); its card styling was lost under <Link asChild> before.

License

MIT