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

@cp949/inspecta-react

v1.0.2

Published

Interactive React component for displaying and editing JSON/JS objects.

Readme

@cp949/inspecta-react

한국어 문서

@cp949/inspecta-react is a React component for exploring and editing JSON and general JavaScript Document Values.

It supports scalar roots, Map, Set, BigInt, circular and shared References, and consumer-defined value adapters.

Installation

pnpm add @cp949/inspecta-react

React and react-dom ^18.0.0 || ^19.0.0 are peer dependencies. Import the stylesheet explicitly:

import Inspecta from "@cp949/inspecta-react";
import "@cp949/inspecta-react/index.css";

export function App() {
  return <Inspecta value={{ hello: "world", count: 1n }} />;
}

Controlled editing

Inspecta never mutates the original value. Editing creates an immutable replacement, which the consumer must publish as the next controlled value:

const [value, setValue] = useState({ user: { name: "Kim" } });

<Inspecta value={value} onChange={(event) => setValue(event.nextRoot)} />;

The handler may return undefined to accept synchronously, or return:

(event, { signal }) => ChangeDecision | PromiseLike<ChangeDecision>;

An accepted decision does not update the viewer until the consumer supplies the new value. A structured rejection keeps the draft and reports an error at the origin path. Cancellation provides local lifecycle shutdown and an AbortSignal, but does not roll back remote side effects. There is no timeout, automatic retry, queue, or optimistic update.

Value adapters

Use forClass for class instances and when for values identified by a consumer type guard.

type Point = readonly [number, number];

const pointAdapter = valueAdapter("point")
  .when(
    (value): value is Point =>
      Array.isArray(value) &&
      value.length === 2 &&
      value.every((item) => typeof item === "number"),
  )
  .scalar((point) => ({
    kind: "point",
    typeLabel: "Point",
    summary: "(" + point[0] + ", " + point[1] + ")",
    tone: "number",
  }))
  .build();

<Inspecta value={[37.5665, 126.978]} adapters={[pointAdapter]} />;

Adapter rules:

  • Consumer adapters are evaluated in registration order before built-ins.
  • Matching, presentation, children, renderer, copy, codec, and replacement phases are synchronous and deterministic.
  • A thrown or Promise-like result fails closed for that occurrence; it does not fall through to another adapter.
  • Collection child tokens identify Document Path segments; labels are display text.
  • Descendant editing requires immutable replace support from every ancestor child.

Copy and redaction

  • strict-json succeeds only when the selected subtree preserves JSON meaning. It does not automatically convert BigInt, Map, Set, symbols, special numbers, binary values, or References.
  • readable produces a deterministic string with type tags and Reference target paths.

An adapter can provide a strictJson projection and call hideRawSelection() to prevent raw values from being exposed through selection.

Selection and diagnostics

<Inspecta
  value={documentValue}
  onSelect={(event) => {
    console.log(event.path, event.adapterId, event.presentation);
    if (event.raw.available) console.log(event.raw.value);
  }}
  onAdapterDiagnostic={(diagnostic) => {
    console.error(diagnostic.adapterId, diagnostic.phase, diagnostic.code);
  }}
/>

Diagnostics are deduplicated by snapshot, path, adapter, phase, and code. A throwing diagnostic callback does not take down the viewer.

Search and accessibility

useJsonSearch is a headless synchronous search hook. The consumer owns the query input and controls navigation with next and previous. Search uses an eager snapshot independent of virtualization.

The tree uses role="tree" and role="treeitem" with roving tabIndex. Arrow keys navigate visible nodes, Enter activates or follows references, Space selects, and F2 enters the action toolbar. Focus returns to the nearest surviving ancestor when the active node disappears.

Virtualization

Virtualization is opt-in:

<Inspecta value={value} virtualization={{ height: 480 }} />

height must be a finite positive number. The viewer owns the fixed viewport and internal scroll. There are no public overscan, measurement, or work-budget options.

Public entry points

  • @cp949/inspecta-react — component, hooks, adapters, and public types
  • @cp949/inspecta-react/index.css — package styles
  • @cp949/inspecta-react/adapter-test — adapter contract test helper

License

MIT