GitHub - khorbushko/JSONInspect: A SwiftUI JSON inspector component for macOS and iOS. Parses arbitrary JSON into an interactive, searchable, and expandable tree view with syntax highlighting — designed for large payloads and IDE-like UX. · GitHub
Skip to content

khorbushko/JSONInspect

Folders and files

Repository files navigation

JSONInspector


Swift ICONKit-license verions

🇺🇦

A SwiftUI JSON inspector component for macOS and iOS. Parses arbitrary JSON into an interactive, searchable, and expandable tree view with syntax highlighting — designed for large payloads and IDE-like UX.

Features

  • Full JSON type support — objects, arrays, strings, numbers, booleans, and null
  • Off-main-thread parsing — actor-isolated parser handles 5MB+ payloads without UI freezing
  • Expand/collapse tree — per-node state, expand all, collapse all, expand up to depth N
  • Syntax highlighting — type-aware coloring for keys, values, brackets, and separators
  • Full-text search — incremental search across keys, values, and paths with match navigation (Cmd+G / Shift+Cmd+G)
  • JSON path filtering — filter by exact path ($.user.name) or wildcard ($[*].id)
  • Breadcrumb navigation — shows canonical path of the selected node with one-click copy
  • 7 built-in themes — Xcode Dark/Light, Monokai, Solarized Dark/Light, GitHub Dark/Light
  • Localization — built-in English and Ukrainian, fully customizable string table
  • IDE-like UI — monospaced typography, line numbers, indent guides, disclosure animation, hover effects (macOS), context menus
  • Modern Swift@Observable, Swift Concurrency, Sendable, immutable node models

Requirements

Platform Minimum
macOS 14.0
iOS 17.0
Swift 5.10

Installation

Swift Package Manager

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/khorbushko/JSONInspect", from: "1.0.0")
]

Or in Xcode: File → Add Package Dependencies and paste the repository URL.

Quick Start

import JSONInspector

struct ContentView: View {
    let jsonString = """
    {"user": {"name": "Alice", "tags": ["swift", "ios"]}}
    """

    var body: some View {
        JSONTreeView(json: jsonString)
    }
}

Configuration

Custom Style & Locale

JSONTreeView(
    json: jsonString,
    configuration: JSONTreeConfiguration(
        showLineNumbers: true,
        expansionStrategy: .upToDepth(2),
        style: .build(.monokai),
        localization: JSONTreeLocalization(locale: .uk)
    )
)

Available Themes

JSONTreeViewStyle.build(.xcodeDark)      // default
JSONTreeViewStyle.build(.xcodeLight)
JSONTreeViewStyle.build(.monokai)
JSONTreeViewStyle.build(.solarizedDark)
JSONTreeViewStyle.build(.solarizedLight)
JSONTreeViewStyle.build(.gitHubDark)
JSONTreeViewStyle.build(.gitHubLight)

External State Control

@State private var search = JSONSearchEngine()
@State private var expansion = JSONExpansionStore()

JSONTreeView(
    json: jsonString,
    searchEngine: search,
    expansionStore: expansion
)

// Programmatic control
Button("Expand All") { expansion.expandAll() }
Button("Search") { search.search("alice") }

JSON Path Filtering

Type a path into the bottom filter bar to narrow the tree:

Path Result
$.user.name Shows the single node at that path
$[*].id Array of all id fields from root elements
$.data[*].tags[*] Nested wildcard fan-out

Custom Localization

let german = JSONTreeLocalization(
    searchPlaceholder: "Suchen…",
    expandAll: "Alle aufklappen",
    collapseAll: "Alle zuklappen"
)

JSONTreeView(
    json: jsonString,
    configuration: .init(localization: german)
)

Architecture

Sources/JSONInspector/
├── Model/               # Immutable data structures
│   ├── JSONNode.swift          # Tree node (Identifiable, Sendable, Hashable)
│   ├── JSONType.swift          # object | array | string | number | bool | null
│   └── FlatRow.swift           # Flattened row for lazy rendering
├── Logic/               # Business logic (no SwiftUI imports)
│   ├── JSONTreeParser.swift    # Actor-isolated JSON → JSONNode parser
│   ├── JSONExpansionStore.swift # Observable expand/collapse state
│   ├── JSONSearchEngine.swift  # Full-text search with index cache
│   └── JSONPathResolver.swift  # Path resolution with [*] wildcards
├── UI/                  # SwiftUI views
│   ├── JSONTreeView.swift      # Main public view
│   ├── JSONTreeRenderer.swift  # LazyVStack + ScrollViewReader
│   ├── JSONRowView.swift       # Individual row rendering
│   ├── JSONSearchBar.swift     # Search input + navigation
│   ├── JSONToolbar.swift       # Expand/Collapse All + node count
│   ├── JSONBreadcrumbView.swift # Path breadcrumb + copy/apply
│   ├── JSONPathInputView.swift # Path filter input
│   └── PlatformHelpers.swift   # macOS/iOS abstractions
└── Configuration/       # Customization
    ├── JSONTreeConfiguration.swift # Top-level config
    ├── JSONTreeViewStyle.swift     # 7 theme presets
    └── JSONTreeLocalization.swift  # en/uk + custom strings

Testing

Some tests across 10 suites covering all logic components:

swift test
Suite Tests
JSONTreeParser 28
JSONExpansionStore 22
JSONSearchEngine 21
JSONPathResolver 34
JSONNode 5
JSONType 3
FlatRow 4
JSONTreeConfiguration 2
JSONTreeLocalization 12
ExpansionStrategy 1

License

MIT licensed.

Thanks to

Contact

Have a question or an issue about JSONInspect? Create an issue!

If you would like to contribute - just create a pull request.


About

A SwiftUI JSON inspector component for macOS and iOS. Parses arbitrary JSON into an interactive, searchable, and expandable tree view with syntax highlighting — designed for large payloads and IDE-like UX.

Resources

License

Stars

Watchers

Forks

Packages

Contributors

Languages