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

@devlens/ui

v1.3.0

Published

DevLens UI Panel - visual issue overlay for browser debugging

Readme

@devlens/ui

A visual debug panel that shows every runtime issue in your app -- right in the browser.

Console logs scroll away. You miss the warning that fired 30 seconds ago. You can't filter, you can't search, you can't export.

DevLens UI gives you a floating debug panel -- isolated in Shadow DOM, fully filterable, searchable, and exportable. One line of code.

What You Get

  • Floating panel -- toggle with Ctrl+Shift+D, never leaves your viewport; button shows a lens icon with the shortcut on hover
  • Two views -- issue list and timeline (chronological)
  • Filter by severity -- error, warn, info, or all
  • Filter by category -- network, null-access, render-data, and more
  • Full-text search -- type to filter issues by message, path, category, or source
  • Issue details -- click any issue row to expand path, value, source, suggestion, and stack trace
  • Session persistence -- issues survive page reloads via localStorage
  • Export -- download all issues as JSON or CSV
  • Badge count -- issue count with pulse animation on new issues
  • Dark and light themes -- matches your preference
  • Shadow DOM isolation -- panel styles never conflict with your app
  • Production-safe -- auto-disabled in production, zero overhead
  • Dashboard opener -- auto-open the hosted DevLens dashboard on first issue, or add a manual button to the panel

Installation

npm install @devlens/core @devlens/ui

Quick Start -- One Line

import { createDetectionEngine } from '@devlens/core';
import { createDevLensPanel, createPanelReporter } from '@devlens/ui';

const { panel, reporter, destroy } = createDevLensPanel({
  position: 'bottom-right',  // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
  theme: 'dark',             // 'dark' | 'light'
  hotkey: 'ctrl+shift+d',   // customizable hotkey
});

const engine = createDetectionEngine({ reporter });

// That's it. Issues now appear in the panel.

With React

import { DevLensProvider } from '@devlens/react';
import { createDevLensPanel } from '@devlens/ui';

const { reporter } = createDevLensPanel({ theme: 'dark' });

function App() {
  return (
    <DevLensProvider config={{ reporter }}>
      <YourApp />
    </DevLensProvider>
  );
}

With Vue

import { createDevLensPlugin } from '@devlens/vue';
import { createDevLensPanel } from '@devlens/ui';

const { reporter } = createDevLensPanel({ theme: 'dark' });

app.use(createDevLensPlugin({ reporter }));

Panel Configuration

createDevLensPanel({
  position: 'bottom-right',   // toggle button position
  theme: 'dark',              // 'dark' | 'light'
  hotkey: 'ctrl+shift+d',    // keyboard shortcut to toggle
  panelWidth: 420,            // panel width in pixels
  panelHeight: 520,           // panel height in pixels
  defaultOpen: false,         // start with panel open?
  dashboardUrl: 'http://localhost:5173/__devlens__',  // optional: show dashboard button
});

Panel Controls

| Action | How | |--------|-----| | Toggle panel | Click the floating lens button or press Ctrl+Shift+D | | Filter by severity | Click Error / Warn / Info / All buttons | | Search issues | Type in the search bar (filters by message, path, category, source) | | View issue details | Click any issue row to expand | | Switch views | Toggle between List and Timeline in the footer | | Export JSON | Click the JSON button in the header | | Export CSV | Click the CSV button in the header | | Clear all issues | Click the CLR button in the header (turns red on hover) | | Open dashboard | Click the monitor button above the toggle (when dashboardUrl is set) |

Dashboard Opener

Open the hosted DevLens dashboard (served by @devlens/vite) automatically on the first detected issue, or let users open it manually.

Auto-open on first issue

import { createDetectionEngine } from '@devlens/core';
import { createDashboardOpener, createDashboardReporter } from '@devlens/ui';

const opener = createDashboardOpener({
  dashboardUrl: 'http://localhost:5173/__devlens__',
  // sessionId?: string    -- auto-generated if omitted
  // windowName?: string   -- window.open target, default 'devlens-dashboard'
});

const engine = createDetectionEngine({
  reporter: createDashboardReporter(opener),
});

// Dashboard opens automatically in a new tab when the first issue is detected.

Manual control

opener.open();           // open (or focus) the dashboard window
opener.close();          // close it
opener.isOpen            // true if window is currently open
opener.sessionId         // session ID used (append to dashboard URL)
opener.dashboardLink     // full URL: dashboardUrl + '?session=' + sessionId

Panel button

Add a monitor-icon button above the main toggle that opens the dashboard on click:

createDevLensPanel({
  dashboardUrl: 'http://localhost:5173/__devlens__',
});

The button appears 50px above the main toggle, styled consistently with the panel. Hover turns it brand-purple.

With Vite plugin

// vite.config.ts
import devlens from '@devlens/vite';

export default {
  plugins: [devlens()],
  // Dashboard available at http://localhost:5173/__devlens__
};

// main.ts
const opener = createDashboardOpener({
  dashboardUrl: `${location.origin}/__devlens__`,
});
const engine = createDetectionEngine({
  reporter: createDashboardReporter(opener),
});

Inspector Window

The inspector opens a separate popup window (or navigates to a hosted dashboard URL) with full sidebar navigation, issue detail view, timeline, and AI Analysis.

import { createDevLensInspector, createInspectorReporter } from '@devlens/ui';

// Legacy popup mode
const inspector = createDevLensInspector();

// Or point at a hosted dashboard
const inspector = createDevLensInspector({
  dashboardUrl: 'http://localhost:5173/__devlens__',
});

const engine = createDetectionEngine({
  reporter: createInspectorReporter(inspector),
});

License System

@devlens/ui includes a license key system for gating premium features:

import { createLicenseManager, createFeatureGate, generateLicenseKey } from '@devlens/ui';

const key = generateLicenseKey();
// => "DL-0AK3-M8X2-PQR5-TN7W"

const license = createLicenseManager();
license.activate(key);
console.log(license.isPro()); // true

const gate = createFeatureGate(license);
gate.isEnabled('timeline-view');  // true (Pro)
gate.isEnabled('search');         // true (Free)

Free features: issue-detail, search

Pro features: timeline-view, session-persistence, export-json, export-csv, category-filter

API Reference

Functions

| Export | Description | |--------|-------------| | createDevLensPanel(config?) | Creates the floating panel. Returns { panel, reporter, destroy }. SSR-safe. | | createPanelReporter(panel) | Reporter adapter that feeds issues to the panel. | | createDashboardOpener(config) | Opens the hosted DevLens dashboard in a new window. Returns { open, close, destroy, isOpen, sessionId, dashboardLink }. SSR-safe. | | createDashboardReporter(opener) | Reporter adapter that auto-opens the dashboard on the first issue. | | createDevLensInspector(config?) | Opens a dedicated inspector window. Returns { sendIssue, sendClear, open, close, destroy, connected, isOpen, sessionId, dashboardLink }. SSR-safe. | | createInspectorReporter(inspector) | Reporter adapter that auto-opens the inspector on first issue. | | createAdapter(sessionId) | Low-level BroadcastChannel + postMessage adapter for inspector communication. | | createPanel(host, config?) | Low-level panel constructor (attach to your own host element). | | createPersistenceManager() | localStorage-backed issue persistence (max 200 issues). | | exportAsJSON(issues) | Serialize issues array to formatted JSON string. | | exportAsCSV(issues) | Serialize issues array to CSV string with headers. | | downloadFile(content, filename, mimeType) | Trigger browser file download. | | createLicenseManager() | License key management with localStorage persistence. | | createFeatureGate(license) | Feature access control based on license status. | | generateLicenseKey() | Generate a valid DL-XXXX-XXXX-XXXX-XXXX license key with checksum. |

Types

| Export | Description | |--------|-------------| | PanelConfig | { position?, theme?, hotkey?, panelWidth?, panelHeight?, defaultOpen?, dashboardUrl? } | | PanelInstance | Panel with open(), close(), toggle(), addIssue(), clear(), getIssues(), destroy() | | DashboardOpenerConfig | { dashboardUrl, sessionId?, windowName? } | | DashboardOpenerInstance | { open(), close(), destroy(), isOpen, sessionId, dashboardLink } | | InspectorConfig | { width?, height?, sessionId?, dashboardUrl? } | | InspectorInstance | Inspector with sendIssue(), sendClear(), open(), close(), destroy(), connected, isOpen, sessionId, dashboardLink | | LicenseManager | getStatus(), getInfo(), activate(key), deactivate(), isPro() | | LicenseInfo | { status: LicenseStatus, key: string \| null, expiresAt: number \| null } | | LicenseStatus | 'free' \| 'pro' \| 'invalid' | | FeatureGate | isEnabled(feature), getFreeFeatures(), getProFeatures(), getAllFeatures() | | Feature | 'timeline-view' \| 'session-persistence' \| 'export-json' \| 'export-csv' \| 'issue-detail' \| 'search' \| 'category-filter' | | PersistenceManager | save(issues), load(), clear() | | InspectorAdapter | Low-level adapter with send(), start(), stop(), sendIssue(), sendClear(), connected |

Technical Details

  • ~84KB ESM bundle (panel UI, inspector, dashboard opener, styles, license system)
  • Shadow DOM -- panel styles are completely isolated, never leak into your app
  • Dual ESM + CJS output with full TypeScript declarations
  • SSR-safe -- returns noop instances when document is unavailable
  • Production-safe -- auto-disabled when NODE_ENV === 'production'
  • z-index: 2147483647 -- panel always floats above your app
  • Version-stamped -- footer shows the exact @devlens/core version injected at build time

Roadmap

| Version | Feature | Status | |---------|---------|--------| | v1.0 | Debug panel with filtering, search, export, persistence, license gating | Done | | v1.1 | Inspector window with AI-powered analysis (Gemini, Claude, GPT) | Done | | v1.2 | Inspector dashboardUrl option -- navigate to hosted dashboard instead of Blob popup | Done | | v1.3 | Dashboard opener, panel button, search fix, icon button, polished header actions | Done | | v2.0 | Deep AI integration -- real-time pattern detection across issues, auto-fix generation, CI/CD integration | Planned |

License

MIT -- GitHub -- Changelog