jsont TUI JSON Viewer
A Terminal User Interface (TUI) JSON viewer built with React and Ink. Reads JSON from stdin or files and displays it in interactive formats including tree view, collapsible view, and schema view with jq and JSONata query capabilities.
Architecture
The codebase follows **clean architecture** with feature-driven organization:
Layer Structure
**Entry Point** (`src/index.tsx`): Minimal entry delegating to AppService with error handling**Core Layer** (`src/core/`): Services, utilities, types, config, context - `AppService` orchestrates application lifecycle
- Utilities: terminal management, stdin processing, error handling, LRU caching, CLI parsing
- Data converters: SQL, XML, YAML, CSV, JSON Schema
- YAML configuration system with hot reloading and validation
**Features Layer** (`src/features/`): Domain-organized features (tree, collapsible, search, jq, schema, navigation, help, settings)**Components** (`src/components/`): Providers, content routing, modals, status, keyboard management**Hooks** (`src/hooks/`): State, handlers, calculations, exports**Store** (`src/store/`): Jotai atomic state managementState Management
**Jotai Atomic State**: Global state in `src/store/atoms/` (ui, search, navigation, settings, debug, jq, export)**Typed Hooks**: `src/store/hooks/` (useUI, useSearch, useNavigation, etc.)**AppStateProvider**: Coordinates global application stateKeyboard Input Architecture
**Central Dispatch**: `App.tsx` uses unified `useInput` hook**Handler Delegation**: Routes input to active feature components**Handlers** (`src/hooks/handlers/`): globalHandler, navigationHandler, searchHandler, jqHandler, helpHandler**KeyboardManager**: Coordinates handler registration**Advanced stdin**: Enables keyboard input even in pipe mode (read-then-reinitialize strategy)Key Commands
Development
`npm run dev` - Run in development mode`npm run build` - Bundle with tsup`npm run start` - Run compiled applicationTesting
`npm run test` - Watch mode`npm run test:run` - Run once`npm run test:ci` - CI-optimized (memory-limited, single-threaded)`npm run test:coverage` - Generate coverage reports (HTML at `./coverage/index.html`)`npm run test:coverage:ui` - Interactive coverage viewerCode Quality
`npm run check` - Biome linter and formatter checks`npm run check:write` - Apply safe fixes`npm run type-check` - TypeScript type checking`npm run lint` - Lint source code`npm run lint:fix` - Lint with auto-fix`npm run format` - Format (read-only)`npm run format:write` - Format and writeUsage
```bash
echo '{"key": "value"}' | npm run dev
cat file.json | npm run dev
npm run dev path/to/file.json
```
Technical Stack
**Runtime**: Node.js 18+ with ES Modules**UI**: React 19 + Ink 6.0**Language**: TypeScript (strictest config)**Build**: tsup with path alias support**Testing**: Vitest with coverage**Code Quality**: Biome (linting/formatting), Husky (git hooks)**State**: Jotai (atomic state management)**Key Libraries**: neverthrow (Result type), node-jq, json5, es-toolkit, js-yaml, zod, mutative, defuDevelopment Guidelines
Import Standards
**Always use extensionless imports** for TypeScript files.
**Path Aliases**:
**Development**: `@/*`, `@core/*`, `@features/*`, `@store/*`, `@components/*`, `@hooks/*`**Build**: tsup only supports `@/*`, `@core/*`, `@features/*` — **use supported aliases to avoid build failures****Import Order**: external dependencies → path aliases → relative imports
Example:
```typescript
import { Box, Text } from "ink";
import type { JsonValue } from "@core/types/index";
import { TreeView } from "@features/tree/components/TreeView";
import { useUI } from "@store/hooks/useUI";
import { formatData } from "./utils/formatter";
```
File Organization
Tests co-located with source files (`.spec.ts` suffix)Feature-based organization with clear domain boundariesBarrel exports (`index.ts`) for clean module interfacesError Handling
Use `neverthrow` Result type pattern (no throwing exceptions)Safe operations return `Result<T, E>` typesComprehensive error context and recovery suggestionsTypeScript Configuration
Extends `@tsconfig/strictest` for maximum type safetyModule resolution: "bundler"Path aliases configured in tsconfig.json and build tools`any` types intentionally used for JSON data handlingFeatures
Navigation
**Line Navigation**: j/k, arrow keys**Page Navigation**: Ctrl+f/b (half-page scrolling)**Goto Navigation**: gg (top), G (bottom)**Feature Toggle**: T (tree), S (schema), D (debug), `,` (settings)Interactive Settings TUI
**Access**: `,` key opens settings editor**Two-pane Layout**: Settings list + description/help**Live Preview**: Immediate changes with unsaved state tracking**Navigation**: Tab (switch categories), j/k (navigate fields), Enter/e (edit)**Validation**: Real-time validation with error messages**Persistence**: Ctrl+S (save), Ctrl+R (reset), Ctrl+D (defaults)Configuration
**Location**: `~/.config/jsont/config.yaml`**Hot Reloading**: Changes applied without restart**Validation**: Zod-based schema validation**Structure**: display (interface, json, tree), keybindings (navigation)Data Export
**Formats**: JSON, YAML, CSV, XML, SQL, JSON Schema**SQL Export**: Schema inference, dialect support, data transformation**XML Export**: Hierarchical data with configurable optionsPerformance Optimization
**LRU Cache**: Schema inference (200-entry), debug log formatting (1000-entry)**React Memoization**: Strategic use of `memo`, `useMemo`, `useCallback`**Algorithm Optimizations**: Tree filtering with for-loops for large datasetsCI/CD Optimization
**Memory Constraints**: CI optimized for 6GB max (`NODE_OPTIONS="--max-old-space-size=6144"`)**Test Configuration**: Single-threaded execution, selective test exclusions for memory-intensive tests**Excluded Tests**: Performance benchmarks, large JSON processing, SQL converter, integration testsInstructions for AI Agent
When working with this codebase:
1. **Respect Clean Architecture**: Keep core utilities, features, and components separated. Core layer should not depend on features.
2. **Use Correct Import Paths**: Always use extensionless imports and supported path aliases (`@/*`, `@core/*`, `@features/*`). Do not use `@store/*`, `@components/*`, `@hooks/*` in production code.
3. **Follow Error Handling Patterns**: Use `neverthrow` Result types. Never throw exceptions in utility functions. Return `Result<T, E>` for operations that can fail.
4. **Co-locate Tests**: Place `.spec.ts` files alongside implementation. Ensure tests cover edge cases and error paths.
5. **Maintain State Patterns**: Use Jotai atoms for global state. Define atoms in `src/store/atoms/`, expose via typed hooks in `src/store/hooks/`.
6. **Keyboard Input Handling**: Register keyboard handlers via callback props to KeyboardManager. Do not use `useInput` directly in feature components.
7. **Configuration Changes**: Update Zod schema in `src/core/config/` when adding configuration options. Ensure default values are provided.
8. **Performance Considerations**: Use LRU caching for expensive operations. Profile large dataset handling. Keep CI test exclusions in mind for memory-intensive tests.
9. **Code Quality**: Run `npm run check:write` before committing. Biome enforces double quotes, 2-space indentation, and import organization.
10. **Export Features**: Add new export formats to `src/core/utils/dataConverters/`. Update export handlers in `src/hooks/handlers/exportHandler.ts`.
11. **Testing**: Run `npm run test:coverage` to ensure adequate coverage. Use `npm run test:ci` to validate CI behavior locally.
12. **Documentation**: Update CLAUDE.md when adding new features, changing architecture, or modifying configuration structure.