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

tm-json-viewer-lite

v0.1.0

Published

A lightweight, themeable, accessible React component for viewing and exploring JSON data as an expandable tree.

Readme

tm-json-viewer-lite

A lightweight, dependency-free React component for viewing JSON data as an expandable, searchable, syntax-highlighted tree. Ships as ESM + CommonJS with TypeScript declarations, and injects its own styles at runtime — no CSS import or bundler config required.

Rename the package (in package.json) before publishing to npm if you need a unique name.

Features

  • Expandable/collapsible tree for objects, arrays, strings, numbers, booleans, and null
  • "Expand All" / "Collapse All" toolbar actions
  • Search box with match count and inline highlighting (auto-expands ancestors of a match)
  • Copy-to-clipboard on every value (and the whole document), with a "copied" confirmation
  • Light/dark theme, plus CSS variables for full customization
  • Graceful handling of empty objects/arrays, circular references, and invalid input
  • Keyboard-accessible controls with ARIA labels

Installation

npm install tm-json-viewer-lite

react and react-dom (>=17) are peer dependencies and must already be installed in your app.

Usage

import { JsonViewer } from 'tm-json-viewer-lite';

const data = {
  id: 1,
  name: 'Ada Lovelace',
  active: true,
  tags: ['mathematician', 'writer'],
  address: { city: 'London', country: 'UK' },
  notes: null,
};

export function Example() {
  return <JsonViewer data={data} />;
}

Dark theme

<JsonViewer data={data} theme="dark" />

Start fully expanded, hide search

<JsonViewer data={data} expandAll showSearch={false} />

Control the default expand depth

{
  /* Only the root node starts open; everything below it starts collapsed. */
}
<JsonViewer data={data} defaultExpandDepth={1} />;

Props

| Prop | Type | Default | Description | | -------------------- | ------------------- | --------- | ------------------------------------------------------------------------- | | data | unknown | — | The value to render. Objects, arrays, strings, numbers, booleans, null. | | defaultExpandDepth | number | 1 | Depth up to which nodes start expanded (0 = only the root). | | expandAll | boolean | false | Start every node expanded, overriding defaultExpandDepth. | | showCopyButton | boolean | true | Show copy-to-clipboard controls on values and the toolbar. | | showSearch | boolean | true | Show the search box in the toolbar. | | theme | 'light' \| 'dark' | 'light' | Visual theme. | | className | string | — | Extra class name applied to the root element. | | id | string | — | id applied to the root element. |

Copy-to-clipboard behavior

  • Hover (or focus) a row to reveal its copy icon.
  • Strings copy their raw text, without the surrounding quotes shown in the tree.
  • Numbers, booleans, and null copy their textual form ("42", "true", "null").
  • Objects and arrays copy their complete value as formatted (JSON.stringify(value, null, 2)) JSON.
  • The toolbar's copy button copies the entire document the same way.
  • After a successful copy, the icon becomes a checkmark for ~1.5s, then reverts automatically.
  • Falls back to a hidden-textarea + document.execCommand('copy') if the async Clipboard API is unavailable (e.g. non-secure contexts, older browsers) or its permission is denied.

Search

Type in the search box to match against keys, array indexes, or leaf values (case-insensitive substring match). Matches are highlighted inline, ancestors of a match are auto-expanded, and the toolbar shows a live match count.

Customizing the theme

theme="light" / theme="dark" switch a set of CSS custom properties scoped to the component's root element. To customize colors further, override the variables yourself via className:

.my-viewer {
  --jv-key: #7c3aed;
  --jv-string: #059669;
  --jv-bg: #fafafa;
}
<JsonViewer data={data} className="my-viewer" />

See src/styles.ts for the full list of variables.

Accessibility

  • Expand/collapse controls are real <button> elements with aria-expanded and descriptive aria-labels, operable with Tab and Enter/Space.
  • The tree root has role="tree"; each row is a semantic list item.
  • Copy buttons remain visible and reachable when focused via keyboard, even though they're hidden until hover on a pointer device.
  • The search input has an associated (visually hidden) <label> and a live match-count region.

Handling invalid or unusual data

  • data={undefined} renders a "No data to display" message.
  • A value of an unsupported type (e.g. a Symbol or a bare function passed as the root) renders an inline error message instead of throwing.
  • Circular references are detected and rendered as [Circular Reference] instead of recursing forever.

Development

npm install
npm run dev      # demo app at http://localhost:5173
npm run lint
npm test
npm run build     # builds dist/ (ESM + CJS + .d.ts)
npm run build:demo

License

MIT

tm-json-viewer