🇺🇦
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.
- 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
| Platform | Minimum |
|---|---|
| macOS | 14.0 |
| iOS | 17.0 |
| Swift | 5.10 |
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.
import JSONInspector
struct ContentView: View {
let jsonString = """
{"user": {"name": "Alice", "tags": ["swift", "ios"]}}
"""
var body: some View {
JSONTreeView(json: jsonString)
}
}JSONTreeView(
json: jsonString,
configuration: JSONTreeConfiguration(
showLineNumbers: true,
expansionStrategy: .upToDepth(2),
style: .build(.monokai),
localization: JSONTreeLocalization(locale: .uk)
)
)JSONTreeViewStyle.build(.xcodeDark) // default
JSONTreeViewStyle.build(.xcodeLight)
JSONTreeViewStyle.build(.monokai)
JSONTreeViewStyle.build(.solarizedDark)
JSONTreeViewStyle.build(.solarizedLight)
JSONTreeViewStyle.build(.gitHubDark)
JSONTreeViewStyle.build(.gitHubLight)@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") }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 |
let german = JSONTreeLocalization(
searchPlaceholder: "Suchen…",
expandAll: "Alle aufklappen",
collapseAll: "Alle zuklappen"
)
JSONTreeView(
json: jsonString,
configuration: .init(localization: german)
)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
Some tests across 10 suites covering all logic components:
swift test- JSONViewer for Idea
Have a question or an issue about JSONInspect? Create an issue!
If you would like to contribute - just create a pull request.

