Bash JSON Viewer β jless & JQ_COLORS Guide
Use the free online JSON Pretty Print directly in your browser β no install required.
Try JSON Pretty Print Online βWhen you need a bash JSON viewer for interactive exploration rather than scripting, the standard jq . pipe falls short β output scrolls past the top of the terminal and you have no way to navigate back through a 300-line API response. This guide covers tools built specifically for viewing JSON interactively in the terminal: jless (collapsible tree with vim-key navigation), JQ_COLORS custom color themes, jq -C | less -R colorized paging, shell aliases for daily use, and fx as a Node.js alternative. For scripting, CI/CD, and validation workflows, see the companion Format JSON in Bash guide. For a zero-install browser viewer, the JSON Pretty Print tool works instantly. Examples are tested on Bash 5.x (macOS via Homebrew, Ubuntu 22.04+) and are compatible with Bash 3.2+ (macOS system shell).
- β’
jlessβ the best interactive JSON viewer for the terminal: collapsible tree, vim-keys, incremental search - β’
jq -C . | less -Rβ colorized scrollable pager with no extra install beyond jq - β’
JQ_COLORSβ env variable that customizes jq's ANSI color scheme for every JSON type - β’
fxβ interactive Node.js JSON viewer with mouse support and JavaScript filter expressions - β’
alias jv='jless'β a one-word command makes interactive viewing a muscle memory habit
Interactive vs. Scripted JSON Viewing
Piping JSON to jq . is the right choice when you want formatted output for a small payload, or when the result feeds into another command. It is the wrong choice when you need to explore a 200-field API response β the output flies past the terminal window and leaves you with no way to navigate, collapse sections, or search for a specific field without re-running the command with a filter. Interactive JSON viewers render the same formatted, colorized output inside a persistent pager where you control navigation. The data is identical; the difference is the interface.
# jq . β output scrolls off screen for large responses curl -s https://api.github.com/users/torvalds | jq . # 300+ lines scroll past β you lose context immediately
# jless β opens an interactive pager, nothing scrolls off curl -s https://api.github.com/users/torvalds | jless # Full document visible, collapsible, searchable with j/k/h/l
jq with explicit filters and exit code handling. The Format JSON in Bash guide covers those scripting patterns.jless β Interactive JSON Viewer
jless is a purpose-built terminal JSON viewer. Unlike a plain jq pipe, it renders the document as a persistent collapsible tree: every object and array can be expanded or collapsed independently with l and h, navigation uses vim-style keys, and incremental search finds any key or value instantly. It streams input incrementally, so it opens large files and API responses in under a second regardless of size β where jq buffers the entire document before displaying anything. I reach for jless as the first tool whenever an API response is too large to scan at a glance.
Installation
# macOS brew install jless # Linux β prebuilt binary from GitHub Releases curl -sL https://github.com/PaulJuliusMartinez/jless/releases/latest/download/jless-x86_64-unknown-linux-gnu.tar.gz \ | tar xz sudo mv jless /usr/local/bin/ # Verify jless --version
Basic usage
# Open a local file β interactive tree viewer launches immediately jless api-response.json # Pipe any JSON stream directly into jless curl -s https://api.github.com/users/torvalds | jless # Open with all nodes collapsed to top level (useful starting point for large documents) jless --mode line api-response.json # Load a specific array element and view it in isolation jq '.[0]' deployments.json | jless
Navigation and search in practice
# Inside jless: # # j / β move down # k / β move up # l / β expand node (or Enter) # h / β collapse node # H collapse current + all siblings β high-level overview # L expand everything recursively # # / start forward search β type a key name and press Enter # n / N next / previous search match # # g / gg jump to start # G jump to end # q quit
jless Keyboard Shortcuts Reference
All shortcuts are available immediately after opening jless β no configuration required. The navigation model is intentionally identical to vim so existing muscle memory transfers.
jq -C | less -R β Colorized Paging Without Extra Tools
If jless is not installed and you need a scrollable, colorized view of a JSON response, jq -C . | less -R is a capable fallback. The -C flag forces ANSI color codes even when stdout is a pipe (normally jq strips them), and -R tells less to render those codes instead of printing them as literal text. The result is a fully colorized, scrollable document β without the interactive tree structure of jless. Navigation inside less uses arrow keys or vim-style j/k, and /triggers less's built-in text search.
# Basic colorized pager jq -C . response.json | less -R # From a curl response β -s prevents progress bar from corrupting the JSON stream curl -s https://api.github.com/repos/jqlang/jq | jq -C . | less -R # Sort keys for easier visual scanning, then page jq -CS . config.json | less -R # -C = force color, -S = sort keys (both flags combined) # Add an alias so you never have to type the full pipe again alias jqv='jq -C . | less -R' # Usage: cat response.json | jqv # or: curl -s https://api.example.com/status | jqv
jq -C | less -R buffers the entire formatted output before less can display it. On a 200 MB file this means waiting several seconds and consuming significant memory β the same limitation as plain jq .. For large files, use jless instead, which streams incrementally.JQ_COLORS β Custom Color Themes
JQ_COLORSis an environment variable that overrides jq's default ANSI color scheme. It takes a colon-separated string of seven ANSI attribute;color codes, one per JSON type in this fixed order: null : false : true : numbers : strings : arrays : objects. Each code is in the format attribute;color where attribute is 0 (normal), 1 (bold), 2 (dim), or 4 (underline), and color is a standard ANSI color number (30β37 = standard, 90β97 = bright).
# ANSI color reference for building JQ_COLORS: # Attributes: 0=normal 1=bold 2=dim 4=underline # Colors: 30=black 31=red 32=green 33=yellow # 34=blue 35=magenta 36=cyan 37=white # Bright: 90=bright-black 91=bright-red 92=bright-green 93=bright-yellow # 94=bright-blue 95=bright-magenta 96=bright-cyan 97=bright-white # # Order: null : false : true : numbers : strings : arrays : objects # High-contrast theme for dark terminals (recommended) export JQ_COLORS="1;30:0;91:0;92:0;93:0;32:1;96:1;96" # null=dim-gray, false=bright-red, true=bright-green, # numbers=bright-yellow, strings=green, arrays=bold-cyan, objects=bold-cyan # Solarized-style theme export JQ_COLORS="2;37:0;35:0;35:0;36:0;33:1;34:1;34" # null=dim-white, false=magenta, true=magenta, # numbers=cyan, strings=yellow, arrays=bold-blue, objects=bold-blue # Minimal (bold keys only, everything else plain) export JQ_COLORS="0;90:0;39:0;39:0;39:0;39:1;39:1;39"
# Add your chosen theme to ~/.bashrc or ~/.zshrc so it applies to every jq call
echo 'export JQ_COLORS="1;30:0;91:0;92:0;93:0;32:1;96:1;96"' >> ~/.bashrc
source ~/.bashrc
# Test the theme
echo '{"active":true,"errors":null,"count":42,"tags":["api","v2"],"meta":{"version":"1.0"}}' | jq .JQ_COLORS must have exactly seven colon-separated values. If the string has fewer segments, jq silently falls back to its built-in defaults without any error message β making misconfiguration hard to diagnose. Always test a new color string on a short JSON payload before adding it to your shell profile.Shell Aliases for Daily JSON Viewing
The commands for interactive JSON viewing are verbose by default. A small set of aliases in ~/.bashrc or ~/.zshrc makes jless and colorized paging single-word commands that integrate naturally into any workflow. The aliases below compose β jv and jvp both accept piped input or a filename as the first argument.
# Add to ~/.bashrc or ~/.zshrc
# jv β interactive viewer (jless if available, colorized pager fallback)
jv() {
if command -v jless &>/dev/null; then
jless "$@"
else
jq -C . "$@" | less -R
fi
}
# jvp β view with keys sorted alphabetically (useful for comparing responses)
alias jvp='jq -CS . | less -R'
# jvc β view from clipboard (macOS)
alias jvc='pbpaste | jless'
# jvf β view and filter: jvf '.users[0]' response.json
jvf() {
local filter="$1"; shift
jq -C "$filter" "$@" | less -R
}
# Reload without restarting terminal
source ~/.bashrc# Usage examples after adding aliases above # View any file or piped response jv deployment-config.json curl -s https://api.github.com/users/torvalds | jv # View sorted (easy to scan alphabetically) cat feature-flags.json | jvp # Drill into a sub-document interactively jvf '.database' infra/app-config.json jvf '.users[] | select(.role == "admin")' users.json
bat β Syntax-Highlighted JSON File Viewing
bat is a cat replacement with syntax highlighting, line numbers, and a built-in pager. For JSON files on disk it provides a clean, editor-style reading experience without opening a full text editor. Unlike jless, bat renders the file as static text β no collapse, no search, no navigation beyond scrolling. Its strength is visual clarity for medium-sized static files (configs, fixtures, test payloads) where you want syntax color and line numbers but do not need interactive tree navigation.
# macOS brew install bat # Debian / Ubuntu (binary may be named batcat) apt-get install -y bat # alias bat=batcat # add to ~/.bashrc if needed on Ubuntu # View a JSON file with syntax highlighting and line numbers bat config/feature-flags.json # Disable pager β print directly to terminal (useful in scripts) bat --paging=never api-response.json # Combine with jq: format with jq, view with bat (preserves bat's JSON highlighting) jq '.' response.json | bat --language=json --paging=never
bat for reading static config files and test fixtures where line numbers matter (e.g., when a test failure references line 47 of a fixture file). For API responses and dynamic JSON from curl, jless is faster to open and more practical to navigate. If you need to view in the browser and share with a colleague, paste directly into the JSON Pretty Print tool β no terminal required.fx β Interactive Node.js JSON Explorer
fx is an interactive JSON viewer built on Node.js. Its interface is similar to jless β collapsible tree, keyboard navigation, search β but it adds two features jless lacks: mouse support (click to expand/collapse nodes) and the ability to type a JavaScript expression in the bottom bar to filter the document in real time. For teams already running Node.js, fx is a natural fit and requires no separate binary. For pure terminal environments without Node, jless is the leaner choice.
# Install globally via npm npm install -g fx # Or run without installing (npx caches the package) curl -s https://api.github.com/users/torvalds | npx fx # Basic interactive use fx api-response.json curl -s https://api.github.com/repos/jqlang/jq | fx # In fx: arrow keys navigate, Enter expands/collapses, / searches # Bottom bar accepts JavaScript expressions for live filtering: # .name β show only the "name" field # .repos.slice(0,5) β first 5 repos
# fx also works as a non-interactive formatter (like jq . but with JS syntax)
# Pass a JavaScript expression as argument β no interactive mode
echo '{"users":[{"id":1,"name":"Sarah Chen"},{"id":2,"name":"Marcus Osei"}]}' \
| fx '.users[0].name'
# Sarah Chen
# Chain with map for array transformations
cat deployments.json | fx '.items.map(d => ({id: d.deploy_id, status: d.state}))'Common Mistakes
These four mistakes come up repeatedly when developers first start using terminal JSON viewers β each one has a clear fix once you understand why it happens.
Problem: jq . dumps all output to stdout at once. For responses longer than your terminal height, everything above the last screenful is gone β you cannot scroll back to the beginning or navigate to a specific field.
Fix: Pipe to jless for interactive navigation, or use jq -C . | less -R as a fallback. Both keep the full document accessible regardless of its size.
# 300-line API response β top 280 lines immediately scroll off curl -s https://api.github.com/users/torvalds | jq . # Only the bottom of the output is visible β cannot navigate back
# Full document stays accessible in jless β nothing is lost curl -s https://api.github.com/users/torvalds | jless # j/k to scroll, h/l to collapse/expand, / to search
Problem: JQ_COLORS requires exactly seven colon-separated values. If the string has six or eight values, jq silently ignores the entire variable and falls back to its compiled-in defaults β no warning, no error, just the wrong colors.
Fix: Count the colons: a valid JQ_COLORS string has exactly six colons and seven values. Echo the variable and pipe to tr to count.
# Only 6 values β jq silently uses defaults, no indication of why
export JQ_COLORS="1;30:0;91:0;92:0;93:0;32:1;96"
echo '{"ok":true}' | jq . # colors unchanged β no error shown# Exactly 7 values β 6 colons export JQ_COLORS="1;30:0;91:0;92:0;93:0;32:1;96:1;96" # Verify the count before adding to shell profile echo "$JQ_COLORS" | tr -cd ':' | wc -c # must output 6
Problem: jless and fx render their interactive interface to the terminal (a TTY), not to stdout. Piping them into grep, tee, or any other command produces garbled ANSI escape codes or empty output β the viewer's interactive output is not designed to be consumed by other programs.
Fix: Use jq with an explicit filter to extract data programmatically. Use jless and fx only as the final step in a pipeline when a human is reading the output.
# jless output is for human eyes β piping it produces garbage jless response.json | grep "request_id" # Output: ANSI escape codes and cursor sequences, not clean text
# Use jq for programmatic extraction β clean, composable jq -r '.request_id' response.json | grep "req_" # Use jless only as the terminal endpoint β nothing after it jless response.json
Problem: -C forces ANSI color codes into the output stream. When that stream is printed directly to a terminal that is not in raw mode β or piped to a tool that does not interpret ANSI β the escape sequences appear as literal characters like ^[[1;34m cluttering the output.
Fix: Always pair jq -C with less -R. The -R flag puts less into raw-input mode, telling it to render ANSI sequences as colors instead of printing them as text.
# -C without -R: escape sequences print as raw text jq -C . response.json | less # Output: ^[[1;34m"status"^[[0m: ^[[0;32m"ok"^[[0m ...
# -C with -R: ANSI codes are rendered as actual colors jq -C . response.json | less -R # Output: colorized JSON, clean and readable
jless vs jq vs bat vs fx β Interactive Viewer Comparison
All four tools render colorized JSON, but their interactive capabilities differ significantly. Choose based on whether you need collapsible navigation, search, or mouse support β and whether Node.js is already in your environment.
For most situations: install jless once and use it as the default interactive viewer. Keep jq -C . | less -R as a fallback for environments where you cannot install additional binaries. Add fx if your team is Node.js-first and values mouse navigation or live JavaScript filtering.
Frequently Asked Questions
How do I search for a specific key inside a JSON file in the terminal?
In jless, press / to open an incremental search prompt, type the key name, and press Enter. Use n to jump forward through matches and N to jump backward. Searching is case-sensitive by default. In jq -C | less -R, / triggers less's built-in search, which matches raw text including ANSI color codes β jless search is more reliable for structured JSON.
# Open file in jless, then press / to search jless api-response.json # In jless: type / β "request_id" β Enter β n for next match # jq alternative: extract and print all matching keys to stdout jq '.. | objects | with_entries(select(.key == "request_id"))' api-response.json
How do I navigate a deeply nested JSON structure with keyboard shortcuts?
jless mirrors vim navigation: j/k for up/down, h to collapse a node, l to expand it. Press H to collapse the current node and all its siblings at once β useful for getting a high-level overview before drilling into a specific branch. L expands everything recursively. Once you have collapsed everything to the top level, expand only the path you care about with l.
# Open the response in jless curl -s https://api.github.com/repos/jqlang/jq | jless # In jless: # H β collapse all top-level keys # j/k β navigate to the key you want # l β expand only that branch # gg β return to root # G β jump to last element
How do I make jq color output easier to read on a dark terminal?
Set the JQ_COLORS environment variable with ANSI attribute;color codes for each JSON type. The seven positions are, in order: null, false, true, numbers, strings, arrays, objects. Put the export in ~/.bashrc or ~/.zshrc to apply it to every jq call. Bold bright colors work best on dark backgrounds.
# High-contrast theme for dark terminals β add to ~/.bashrc or ~/.zshrc
export JQ_COLORS="1;30:0;91:0;92:0;93:0;32:1;96:1;96"
# null=gray, false=bright-red, true=bright-green,
# numbers=bright-yellow, strings=green, arrays/objects=bright-cyan
# Test immediately without reloading shell
echo '{"active":true,"errors":0,"tags":["api","v2"]}' | jq .What is the difference between jless and jq . for viewing JSON?
jq . scrolls output past the top of the terminal and gives you no way to navigate back β useful for small responses, but impractical for anything over 50 lines. jless renders the entire document in an interactive pager where you can scroll, search, collapse nodes, and navigate with keyboard shortcuts without losing context. Use jq . when you want to glance at a small payload; use jless when you need to explore.
# Small payload β jq . is fine
echo '{"status":"ok","version":"2.4.1"}' | jq .
# Large or nested response β jless is better
curl -s https://api.github.com/repos/jqlang/jq | jless
# β interactive tree, no output scrolled off screenHow do I view JSON from a curl response interactively in the terminal?
Pipe curl directly into jless. Always include -s (silent) to prevent curl's progress bar from appearing in the output. jless will open the interactive viewer with the full response rendered as a collapsible tree. If jless is not installed, jq -C . | less -R gives a colorized pager as a fallback.
# Interactive exploration with jless curl -s https://api.github.com/users/torvalds | jless # Colorized pager fallback (no collapse, but still scrollable with color) curl -s https://api.github.com/users/torvalds | jq -C . | less -R
Can I view multiple JSON files side by side in the terminal?
jless opens one file at a time. For side-by-side comparison, use a terminal multiplexer: tmux split-window -h opens a vertical split, then run jless in each pane with a different file. Alternatively, use the browser-based JSON Diff tool if you need to compare two documents structurally.
# tmux side-by-side: split horizontally, then run jless in each pane tmux split-window -h # Left pane: jless response-v1.json # Right pane: jless response-v2.json # Or use diff on jq-normalized output for a text diff diff <(jq -S . response-v1.json) <(jq -S . response-v2.json)
Related Tools
The JSON Pretty Print tool gives you the same collapsible, colorized view as jless β directly in the browser, with no installation and no terminal required.
Cora is a platform engineer who builds developer tooling and internal platforms, using Bash as the glue that connects components written in different languages and runtimes. She writes about cross-platform shell scripting, Bash utility functions, environment management, configuration templating, and the practical shell techniques that platform engineers use to build self-service tooling for development teams.
Nadia is a site reliability engineer who lives in the terminal. She writes Bash scripts that process logs, transform data, and orchestrate infrastructure across fleets of servers. She is a heavy user of jq, awk, and sed and writes about shell one-liners, text processing pipelines, data serialisation from the command line, and the practical Bash patterns that SREs reach for when speed matters more than elegance.