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

@jfdevelops/react-layout-devtools-core

v1.0.0

Published

Framework-independent layout inspection protocol and graph store.

Readme

React Layout Devtools Core

A framework-independent inspection protocol, external store, and deterministic graph layout. No React or DOM dependency. The React adapter uses this package; future adapters can subscribe to the same sources.

import { getInspectionSource, layoutGraph } from '@jfdevelops/react-layout-devtools-core';

const source = getInspectionSource(layouts);
const unsubscribe = source.subscribe(() => {
  const graph = source.getSnapshot();
  const positions = layoutGraph(graph);
  // Update your adapter.
});
// Read once immediately, too: sources retain activity before subscription.
const graph = source.getSnapshot();
// Dispose when your adapter is removed:
unsubscribe();

Snapshots have readonly nodes and edges; node IDs remain stable for the lifetime of a definition. active is a mounted instance count, and unresolved describes lazy declarations. Edges distinguish containment, definitions, rendering, declared composables, and explicit references. A snapshot retains its identity until the source changes, making it compatible with external-store adapters.

Core exports InspectionSource, GraphSnapshot, GraphNode, GraphEdge, layoutInspection, createInspectionStore, inspectionId, and layoutGraph, and buildInspectionTree. The producer API registers metadata and mount lifecycles; consumers should depend on InspectionSource. Sources retain metadata for their factory/definition lifetime; activity is removed on unmount.

describePropValidator and formatInspectionDetails turn validator metadata into readable types without calling validators or render callbacks. Descriptions include required/optional visibility, literal/enum values, unions, nested object properties, records, React nodes/elements, and render-prop signatures. Ordinary functions remain explicitly labeled as functions; circular structures are handled safely.

Development adapters may supply source / registrationSource on graph nodes and opt into the layoutDebug metadata symbol. Source locations contain a file, line, column, and optional same-origin editor URL. Producers can register mounted PreviewInstance entries with registerPreview; adapters use the optional preview(instanceId, stateId?) command and connectPreview() session lifetime. Omitting the state returns an instance to Auto. Composed stores route commands to the owning producer; the final inspector disconnect resets forced instances.

Shared settings and preferences

Every UI adapter can use DevtoolsConfig, DevtoolsPreferences, and DevtoolsSessionState. Core owns the palette, graph/tree settings, zoom bounds, filters, details visibility, defaults, validation, nested merging, and the saved preference schema. It has no React, DOM, or storage dependency.

import {
  defaultDevtoolsStorageKey,
  parseDevtoolsPreferences,
  mergeDevtoolsPreferences,
  serializeDevtoolsPreferences,
  resolveChipColors,
} from '@jfdevelops/react-layout-devtools-core';

const config = { initialZoom: 0.75 };
const preferences = parseDevtoolsPreferences(storage.read(defaultDevtoolsStorageKey), config);
const updated = mergeDevtoolsPreferences(preferences, {
  initialFilters: { activeOnly: true },
});

storage.write(defaultDevtoolsStorageKey, serializeDevtoolsPreferences(updated));
const palette = resolveChipColors(updated.chipColors);

// Reset to the caller's configuration, falling back to the shared defaults.
const reset = parseDevtoolsPreferences(null, config);

The adapter supplies storage.read / storage.write and subscription events. Malformed saved values fall back to caller defaults; nested updates merge by key. The existing react-layout-devtools:preferences:v1 key and flat saved format are retained for compatibility. defaultDevtoolsPreferences exposes the built-in values without requiring storage.

DevtoolsSessionState describes temporary search and selection. Mounted instances and forced render states remain part of the inspection protocol. None of these are included by serializeDevtoolsPreferences. Adapter-specific settings, such as the React FAB coordinates, are handled by that adapter rather than added to the shared schema. Build-tool options such as production inclusion and source instrumentation remain with the build adapter.