RepoPilotOpen in app →

tidwall/gjson

Get JSON values quickly - JSON parser for Go

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1d ago
  • 14 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Single-maintainer risk — top contributor 83% of recent commits
  • No test directory detected

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/tidwall/gjson)](https://repopilot.app/r/tidwall/gjson)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/tidwall/gjson on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: tidwall/gjson

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/tidwall/gjson shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 1d ago
  • 14 active contributors
  • MIT licensed
  • CI configured
  • ⚠ Single-maintainer risk — top contributor 83% of recent commits
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live tidwall/gjson repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/tidwall/gjson.

What it runs against: a local clone of tidwall/gjson — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in tidwall/gjson | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>tidwall/gjson</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of tidwall/gjson. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/tidwall/gjson.git
#   cd gjson
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of tidwall/gjson and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "tidwall/gjson(\\.git)?\\b" \\
  && ok "origin remote is tidwall/gjson" \\
  || miss "origin remote is not tidwall/gjson (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "gjson.go" \\
  && ok "gjson.go" \\
  || miss "missing critical file: gjson.go"
test -f "SYNTAX.md" \\
  && ok "SYNTAX.md" \\
  || miss "missing critical file: SYNTAX.md"
test -f "gjson_test.go" \\
  && ok "gjson_test.go" \\
  || miss "missing critical file: gjson_test.go"
test -f "go.mod" \\
  && ok "go.mod" \\
  || miss "missing critical file: go.mod"
test -f "README.md" \\
  && ok "README.md" \\
  || miss "missing critical file: README.md"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/tidwall/gjson"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

GJSON is a high-performance JSON parser and query library for Go that retrieves values from JSON documents using dot-notation path syntax (e.g., "name.last") without unmarshaling the entire document. It excels at fast, targeted JSON value extraction with features like wildcard patterns, array indexing, and JSONLines support, making it ideal for scenarios where you only need specific fields from large JSON payloads. Single-package design: gjson.go is the core parser/querier with a Result type encapsulating parsed values, supporting chaining via method receivers (e.g., result.Get(subpath)). Zero monorepo structure—just gjson_test.go for unit tests, SYNTAX.md documenting the path language, and companion tools (SJSON for mutations, JJ CLI) available in separate repos. Dependencies imported cleanly via go.mod.

👥Who it's for

Go developers building APIs, data pipelines, or services that need to quickly extract specific values from JSON responses or logs without the overhead of full unmarshaling into structs. Common use cases: REST API clients filtering responses, log aggregation systems parsing structured logs, and CLI tools querying JSON data files.

🌱Maturity & risk

Production-ready and actively maintained. The repo shows a focused, single-file implementation (gjson.go ~3000 LOC) with comprehensive test coverage (gjson_test.go), CI/CD via GitHub Actions (.github/workflows/go.yml), and explicit Go 1.23 support in go.mod. The minimalist design and stable API suggest a mature, battle-tested library used widely in production Go codebases.

Minimal risk. Only 2 lightweight dependencies (tidwall/match for glob patterns, tidwall/pretty for formatting) both maintained by the same author, reducing supply-chain exposure. Single-maintainer maintained by Josh Tidwall (tidwall) is a known risk, but the project's simplicity and narrow scope make it less vulnerable to abandonment. No observed breaking changes in API design; straightforward semantic versioning expected.

Active areas of work

The repo appears stable with no obvious active development visible in the file list alone. Last activity cannot be determined from the provided snapshot, but the mature state and lack of TODO markers suggest maintenance mode rather than feature velocity. Check the GitHub commit log and issues for recent activity patterns.

🚀Get running

git clone https://github.com/tidwall/gjson.git
cd gjson
go mod download
go test ./...

Daily commands: No server or CLI to run locally. Use as a library: go get github.com/tidwall/gjson then import "github.com/tidwall/gjson" and call gjson.Get(jsonString, path). For experimentation, visit the GJSON Playground (https://tidwall.com/gjson-play) linked in the README.

🗺️Map of the codebase

  • gjson.go — Core parsing engine implementing GJSON path syntax and JSON value extraction logic; entry point for all query operations
  • SYNTAX.md — Official specification for GJSON path syntax (dot notation, wildcards, arrays); essential reading to understand query capabilities
  • gjson_test.go — Comprehensive test suite covering path parsing, edge cases, and performance benchmarks; defines expected behavior
  • go.mod — Declares minimal dependencies (match, pretty); critical for understanding external coupling and Go version compatibility
  • README.md — High-level API documentation with usage examples, feature overview, and performance characteristics

🧩Components & responsibilities

  • gjson.Get() function (Go stdlib (strings, bytes)) — Entry point; accepts JSON string and path query, orchestrates parsing and navigation
    • Failure mode: Returns null Result if path not found; panics on invalid path syntax
  • Path tokenizer (Go string scanning, tidwall/match) — Breaks dot-notation path into atomic tokens (keys, indices, wildcards, filters)
    • Failure mode: Invalid path syntax halts parsing; returns error in Result
  • JSON navigator (JSON unmarshaling, recursive descent) — Traverses JSON object/array tree following token sequence, handles type mismatches
    • Failure mode: Type mismatch (e.g., expecting array on string) returns null Result
  • Result struct (Go struct, method receivers) — Immutable container for matched value, type, and raw representation
    • Failure mode: Methods on null Result gracefully return zero values

🔀Data flow

  • User codeGet(jsonString, path) — Raw JSON bytes/string and path query string
  • Get()Path tokenizer — Path string broken into tokens (keys, array indices, filters)
  • Path tokensJSON navigator — Tokens guide sequential navigation through JSON object/array structure
  • JSON navigatorResult struct — Located value, its type, and raw representation packaged into Result
  • ResultUser code — Immutable Result object with Type (Number, String, Array, Object, Null), Value, and Raw fields

🛠️How to make changes

Add a new query path function

  1. Define the new exported function signature in gjson.go following the pattern Get(json, path) → Result (gjson.go)
  2. Implement path tokenization and evaluation logic reusing existing path parsing helpers in gjson.go (gjson.go)
  3. Add test cases covering normal, edge, and error conditions in gjson_test.go (gjson_test.go)
  4. Update SYNTAX.md if new path syntax operators are introduced (SYNTAX.md)

Optimize performance for a specific query pattern

  1. Add benchmark test in gjson_test.go using Go's testing.B to measure baseline performance (gjson_test.go)
  2. Profile and optimize the path evaluation or JSON traversal logic in gjson.go (gjson.go)
  3. Verify improvements don't regress other test cases in gjson_test.go (gjson_test.go)

Support a new JSON query syntax feature

  1. Document the new syntax in SYNTAX.md with examples and edge cases (SYNTAX.md)
  2. Implement tokenization and evaluation in gjson.go's path parsing logic (gjson.go)
  3. Add comprehensive test cases in gjson_test.go covering the new syntax (gjson_test.go)
  4. Update README.md examples if it's a significant feature (README.md)

🔧Why these technologies

  • Go — Fast JSON parsing with minimal memory allocation; compiled performance critical for parsing library
  • tidwall/match — Handles glob pattern matching for wildcard and filter expressions in path queries
  • tidwall/pretty — Supports pretty-printing and formatting of parsed JSON results

⚖️Trade-offs already made

  • Single-pass streaming parser approach

    • Why: Maximizes speed for one-off queries without building full AST or intermediate representations
    • Consequence: Limited ability to validate entire JSON structure upfront; errors surface during navigation
  • Minimal dependencies (only match and pretty)

    • Why: Reduce bloat and external attack surface for a core utility library
    • Consequence: Pattern matching and formatting logic tightly coupled; harder to swap implementations
  • Result returned as immutable struct

    • Why: Safer concurrent access and simpler API ergonomics
    • Consequence: No in-place mutations; modifying JSON requires separate SJSON library

🚫Non-goals (don't propose these)

  • Does not modify JSON (separate SJSON library exists for that)
  • Does not handle JSON Schema validation
  • Does not provide streaming JSON parsing for incremental chunked input
  • Does not implement custom JSON unmarshaling to Go structs (use encoding/json for that)

📊Code metrics

  • Avg cyclomatic complexity: ~4.2 — Main gjson.go file mixes tokenization, navigation, and type-handling logic; multiple path traversal strategies (keys, indices, wildcards, filters) add branching
  • Largest file: gjson.go (1,800 lines)
  • Estimated quality issues: ~2 — Minimal code; well-tested. Issues: lack of explicit error types (panic vs null), no path caching leading to redundant parsing on repeated queries

⚠️Anti-patterns to avoid

  • Panic on malformed input (Medium)gjson.go path parsing: Invalid path syntax may cause panic instead of returning graceful error; downstream caller must validate input
  • Silent type coercion on navigation failure (Low)gjson.go JSON navigator: Attempting to navigate array index on non-array silently returns null Result instead of explicit error

🔥Performance hotspots

  • gjson.go token parsing loop (Algorithmic: O(len(path)) per query; optimizable with path memoization) — String scanning and splitting for every path query; no path compilation/caching; repeated tokenization for same path
  • gjson.go JSON unmarshaling during navigation (Memory: O(JSON size) in worst case; could stream large arrays) — Full JSON document may be unmarshaled to intermediate structs for deep paths; no lazy evaluation at deep levels

🪤Traps & gotchas

No environment variables or external services required. Gotchas: (1) Path syntax is positional-sensitive; escaping special chars like dots and wildcards with backslashes is required (e.g., "fav\.movie" for the key "fav.movie"). (2) Get() returns a Result even if the path doesn't exist; check Result.Exists() or Result.Type == gjson.Null. (3) Large JSON parsing is still single-threaded; performance advantage is from early-exit, not concurrency.

🏗️Architecture

💡Concepts to learn

  • Early-exit JSON parsing — GJSON's core performance trick: it doesn't unmarshal the entire JSON into memory; instead it stops scanning as soon as the target path is found. Understanding this is key to knowing when GJSON outperforms full unmarshaling.
  • Token-based streaming vs. tree building — GJSON uses a token stream parser (similar to json.Decoder) rather than building an AST. This keeps memory and CPU low. If you modify GJSON, you'll work with tokens, not tree nodes.
  • Glob pattern matching (wildcards) — GJSON supports * and ? in paths via the tidwall/match dependency. Understanding glob semantics is essential for path queries like friends.*.first (all first names in friends array).
  • Receiver-based fluent API — GJSON's Result type uses method receivers (Get, Array, Object, ForEach) for chaining. Understanding Go's receiver semantics is needed to extend or debug the API.
  • JSONLines format — GJSON natively supports newline-delimited JSON (one object per line), common in streaming logs and data pipelines. The library has specific optimizations for iterating JSONLines without full parsing.
  • Path syntax escape sequences — GJSON allows escaping special characters (dots, wildcards) in path keys with backslashes. This is a subtle but critical feature for querying JSON with literal dots in key names (e.g., config.fav.movie).
  • tidwall/sjson — Sister library for mutating JSON (the write counterpart to GJSON's read). Users often pair them for read-modify-write workflows.
  • tidwall/jj — Command-line tool wrapping GJSON for shell scripting and ad-hoc JSON querying. Shows practical GJSON usage at the CLI layer.
  • jqlang/jq — Gold standard JSON query language with richer filter syntax. GJSON is deliberately simpler and faster; understanding jq helps contextualize GJSON's design choices.
  • buger/jsonparser — Competing Go JSON parser focused on streaming/low-allocation parsing; similar performance goals but different API (element-by-element vs. path-based).
  • tidwall/match — Direct dependency providing glob pattern matching (used for wildcard paths in GJSON). Critical for understanding how *.field and ? queries work internally.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add benchmarking suite in gjson_test.go for performance regression detection

The README emphasizes 'fast' performance as a key feature, but there's no visible benchmark suite in gjson_test.go. Adding comprehensive benchmarks (Benchmark* functions) for common operations (Get, GetMultiple, Parse, path traversals) would help maintainers catch performance regressions in future PRs and give contributors data-driven insights into optimization opportunities.

  • [ ] Add Go benchmark functions (BenchmarkGet, BenchmarkParse, BenchmarkComplexPath) to gjson_test.go
  • [ ] Include benchmarks for different JSON sizes (small, medium, large documents)
  • [ ] Document how to run benchmarks in README.md
  • [ ] Add benchmark comparison results to track performance over versions

Expand SYNTAX.md with real-world examples and edge case documentation

SYNTAX.md exists but the README snippet cuts off mid-sentence about 'dot notation paths', suggesting the syntax documentation may be incomplete. The file likely lacks detailed examples of complex queries, edge cases (null handling, array indexing, nested wildcards), and gotchas that would help users and contributors understand the full feature set.

  • [ ] Review SYNTAX.md and identify undocumented query types or operators
  • [ ] Add 5-10 real-world JSON query examples with expected outputs
  • [ ] Document edge cases (empty arrays, null values, invalid paths, type mismatches)
  • [ ] Add a 'Common Mistakes' section based on likely user confusion points

Add integration tests for the match and pretty dependencies in gjson_test.go

The go.mod shows dependencies on tidwall/match and tidwall/pretty, but there's no visible test coverage for how gjson integrates with these libraries. Adding integration tests would ensure compatibility, document expected behavior with path matching patterns, and catch breakage when upstream dependencies update.

  • [ ] Add tests in gjson_test.go for match-dependent features (wildcard paths, fuzzy matching if applicable)
  • [ ] Add tests for pretty-dependent features (output formatting if gjson exposes it)
  • [ ] Test edge cases where match or pretty might fail gracefully
  • [ ] Verify tests pass with current dependency versions in go.sum

🌿Good first issues

  • Add benchmarks comparing gjson.Get() vs standard json.Unmarshal + field access for various JSON sizes and path depths; would require adding a bench_test.go file with realistic payloads.
  • Expand SYNTAX.md with more complex query examples (e.g., nested wildcard patterns, chained filters on arrays) and add corresponding test cases to gjson_test.go to close any documentation-test gaps.
  • Add godoc examples to gjson.go (see Go's example test pattern) for common use cases like extracting nested fields, iterating arrays, and handling missing keys—improves discoverability for new users.

Top contributors

Click to expand
  • @tidwall — 83 commits
  • @sspaink — 3 commits
  • @V02460 — 2 commits
  • [@Sebastian Spaink](https://github.com/Sebastian Spaink) — 2 commits
  • @rustfix — 1 commits

📝Recent commits

Click to expand
  • 0fac2c9 — Add iterator functions All, Keys, and Values (tidwall)
  • 4d23028 — Add repo url (tidwall)
  • 10d2662 — Add copyright comment (tidwall)
  • 4a91ee1 — Update README.md (tidwall)
  • 133f42c — Generally faster parsing (tidwall)
  • 92dff34 — Update README.md (tidwall)
  • 5ab551f — Add flag for disabling HTML escaping (tidwall)
  • 28d458b — Disable html escaping (tidwall)
  • c2bc5a4 — dark mode logo (tidwall)
  • 2ba56cc — Merge pull request #354 from rustfix/master (tidwall)

🔒Security observations

The GJSON project demonstrates good security posture as a focused JSON parsing library. No critical vulnerabilities were identified. The codebase is minimal with only two well-maintained dependencies (tidwall/match and tidwall/pretty). Primary concerns are operational: ensuring current Go version support, implementing dependency scanning in CI/CD, and maintaining go.sum integrity. The library's narrow scope (JSON parsing without external I/O) inherently limits attack surface. No hardcoded secrets, injection vectors in visible code structure, or infrastructure misconfigurations were detected.

  • Low · Outdated Go Version — go.mod. The go.mod file specifies 'go 1.23' which may not receive security updates indefinitely. While this is not a critical vulnerability, ensuring the project targets a supported Go version is a best practice for long-term security maintenance. Fix: Monitor Go release cycles and update the minimum Go version periodically to ensure access to the latest security patches. Currently Go 1.23 is supported, but plan updates for LTS versions when available.
  • Low · No SBOM or Dependency Scanning Configuration — .github/workflows/go.yml. The repository lacks visible configuration for Software Bill of Materials (SBOM) generation or automated dependency vulnerability scanning in CI/CD pipelines (go.yml workflow is present but content not shown). Fix: Add automated dependency scanning using tools like 'go list -json -m all' in CI/CD or GitHub's built-in dependency scanning. Generate SBOM using tools like syft or cyclonedx for transparency.
  • Low · Limited Dependency Pinning Information — go.sum. While go.mod shows dependencies, the go.sum file content is not provided. Ensure go.sum is committed to the repository and verified in CI/CD to prevent dependency tampering. Fix: Verify that go.sum is tracked in version control and that dependency integrity is validated during builds. Use 'go mod verify' in CI/CD pipelines.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · tidwall/gjson — RepoPilot