Sign In

ink-json-viewer

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ink-json-viewer

Interactive, collapsible JSON tree viewer component for Ink

latest
Source
npmnpm
Version
0.4.0
Version published
Maintainers
1
Created
Source

ink-json-viewer

npm version CI license npm downloads

ink-json-viewer demo

Interactive, collapsible JSON tree viewer component for Ink. Renders any JavaScript value as a navigable, syntax-colored tree in the terminal.

Features

  • Collapsible/expandable tree nodes with expand/collapse all
  • Syntax coloring for 16 value types
  • Full keyboard navigation (arrows, vim-style home/end, expand all, collapse all)
  • Virtual scrolling for large data sets (10K+ nodes)
  • Circular reference detection
  • Customizable color themes
  • TypeScript-first with full type exports
  • Headless hooks for custom UI

Install

npm install ink-json-viewer

Peer dependencies: ink >= 6.0.0 and react >= 19.0.0. Requires Node.js >= 20.

Quick Start

import {render} from 'ink';
import {JsonViewer} from 'ink-json-viewer';

const data = {
  name: 'ink-json-viewer',
  version: '0.3.0',
  features: ['collapsible', 'keyboard nav', 'syntax coloring'],
  config: {maxHeight: 20, theme: 'default'},
  active: true,
  tags: null,
};

render(<JsonViewer data={data} defaultExpandDepth={1} />);

Props API

PropTypeDefaultDescription
dataunknownrequiredThe value to render. Accepts any JS value: objects, arrays, primitives, Date, RegExp, Map, Set, BigInt, Symbol, functions, etc.
defaultExpandDepthnumber1Number of depth levels to expand on initial render. 0 = fully collapsed, Infinity = fully expanded.
maxHeightnumber20Maximum number of visible rows before virtual scrolling kicks in.
showRootBracesbooleantrueWhether to show the outermost brackets for the root value. When false, the root {}/[] rows are omitted and children render at depth 0 (unindented).
sortKeysbooleanfalseAlphabetically sort object keys.
enableKeyboardbooleantrueEnable keyboard navigation and interaction.
indentWidthnumber2Number of spaces per indentation level.
maxStringLengthnumber120Maximum display length for string values before truncation (includes quotes).
onSelect(path: string, value: unknown) => voidundefinedCalled when Enter is pressed on a leaf node. Receives the node id and raw value. The id is a bespoke path (e.g. $.users[0].name), not spec JSONPath: each string key segment has ., [, ], and % percent-encoded, so a key like a.b arrives as $.a%2Eb.
themePartial<JsonViewerTheme>undefinedPartial theme overrides merged with the default theme.
isActivebooleantrueWhether the component is focused/active for keyboard input. Useful when embedding alongside other interactive components.
rootLabelstringundefinedLabel to display for the root node (e.g., the variable name).

Keyboard Shortcuts

KeyAction
Down ArrowMove focus to the next node
Up ArrowMove focus to the previous node
Right ArrowExpand focused node, or move to first child if already expanded
Left ArrowCollapse focused node, or move to parent if already collapsed
EnterToggle expand/collapse on containers; triggers onSelect on leaf nodes
SpaceToggle expand/collapse on containers
gJump to the first node
GJump to the last node
* or eExpand all nodes
- or ECollapse all nodes

Note: Search is planned for a future release.

Syntax Coloring

Each value type renders in a distinct color by default:

TypeColor
stringgreen
numberyellow
booleanmagenta
nullred (dim)
undefinedred (dim)
dategreen
regexpgreen
bigintyellow
symbolgreen (dim)
functionred (dim, italic)
circularred (bold)
objectgray (preview)
arraygray (preview)
mapgray (preview)
setgray (preview)
keyswhite
bracketsgray
focus indicatorblue

Supported Value Types

The viewer detects and renders 16 value types:

TypeRendered As
string"hello" (with escaping for \n, \t, \\, \")
number42, 3.14, -1
booleantrue, false
nullnull
undefinedundefined
dateISO string, e.g. 2024-01-15T00:00:00.000Z. Invalid dates render as Invalid Date.
regexp/pattern/flags
bigint42n
symbolSymbol(description)
function[Function: name]
objectExpandable tree with {N keys} collapsed preview
arrayExpandable tree with [N items] collapsed preview
mapExpandable tree with Map(N) preview
setExpandable tree with Set(N) preview
circular[Circular] (bold red)
unknown[Max depth exceeded] when nesting exceeds 100 levels

Virtual Scrolling

When the visible row count exceeds maxHeight, the viewer enables virtual scrolling. Only maxHeight rows are rendered at a time. Scroll indicators appear at the top and bottom to show how many rows are hidden:

  ^ 3 more
  ...visible rows...
  v 12 more

The scroll window automatically follows the focused row as you navigate.

Theme Customization

Override any color by passing a partial theme prop:

<JsonViewer
  data={myData}
  theme={{
    colors: {
      string: 'cyan',
      number: 'blueBright',
      focusIndicator: 'greenBright',
    },
  }}
/>

All color values are Ink/Chalk color names (e.g., 'red', 'greenBright', 'gray').

Available theme keys: string, number, boolean, null, key, bracket, expandIcon, focusIndicator, circular, preview.

Large Data

The component keeps rendering cheap even for large data sets:

  • Eager flatten, then windowed render: flattenTree walks the entire input once up front, so the initial flatten is O(total nodes). After that, only the visible window is rendered.
  • Virtual scrolling: Only maxHeight rows are rendered at any time, keeping the rendered output size constant regardless of data size.
  • Collapsed subtrees skipped on render: Children of collapsed containers are skipped at the visible-row computation stage, so a collapsed tree stays cheap to display even though every node was flattened.
  • Immutable state updates: The reducer produces new state objects without mutating previous state.

The whole input is flattened up front, so extremely large inputs still pay an O(total nodes) cost per data change. For data with 10,000+ nodes, set defaultExpandDepth to 0 or 1 and rely on maxHeight (default 20) to keep the render fast. Users can expand sections on demand.

Headless Usage

For custom UI, import the hooks and utilities directly:

import {
  useJsonViewerState,
  useJsonViewer,
  flattenTree,
  buildNodeIndex,
  detectType,
  formatValue,
  formatKey,
  truncate,
  defaultTheme,
  mergeTheme,
} from 'ink-json-viewer';

import type {JsonViewerState} from 'ink-json-viewer';
  • useJsonViewerState(props) is the headless state hook: it returns the full JsonViewerState (visible rows, focus, expand state, and navigation methods like focusNext() / expandAll()) for rendering your own rows
  • useJsonViewer({state, isActive, onSelect}) wires the default keyboard bindings (arrows, g/G, expand/collapse, select) onto a JsonViewerState
  • flattenTree(data, options?) converts any value into a flat JsonNode[] array
  • buildNodeIndex(nodes) creates a Map<string, JsonNode> for O(1) lookups
  • detectType(value) returns the JsonValueType for any value
  • formatValue(value, type, maxStringLength) formats a value for display
  • formatKey(key) formats a property key (quoting if needed)
  • truncate(string, maxLength) truncates with ellipsis
  • defaultTheme / mergeTheme(base, overrides) for theme management
  • JsonViewerState is the full state object returned by the internal useJsonViewerState hook, including navigation methods like focusNext(), expandAll(), etc.

TypeScript

All types are exported for use in your own components:

import type {
  JsonValueType,     // Union of all 16 type strings
  JsonNode,          // A node in the flattened tree
  VisibleRow,        // A row in the visible output
  JsonViewerTheme,   // Color theme shape
  JsonViewerProps,   // Component props
  JsonViewerState,   // Full viewer state with navigation methods
  ExpandState,       // ReadonlyMap<string, boolean> of expanded nodes
  TreeState,         // Internal reducer state
} from 'ink-json-viewer';

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

  • Fork the repository
  • Create a feature branch (git checkout -b my-feature)
  • Make your changes and add tests
  • Run npm test and npx tsc --noEmit to verify
  • Commit and open a pull request

Changelog

See GitHub Releases.

License

MIT

Keywords

ink

FAQs

Package last updated on 25 Jul 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts