Explore nested data in your browser or terminal.
Twig is a local JSON, YAML, and HAR explorer. Follow a branch, search keys and values, jump to a path, and copy the value you need without losing your place. The web app and terminal interface share one Rust engine, familiar keyboard controls, and two themes: Dark and Light.
Open the web explorer · Install the terminal app · User guide · Releases
In the browser, open twig.wtf, then drop a file, choose Open file, or select Paste data. A bundled example is ready to explore before you open anything. Files are processed in your browser and are not uploaded.
In the terminal, install Twig and open a file:
twig data.json
twig config.yaml
twig network.harSelect a row to inspect it. Press Enter to open a container, Esc to go back,
/ to search, and ? to see the shortcuts. Both explorers leave the original
file unchanged. Formatting and JSON repair are separate CLI commands.
| Choose | When it fits | Where document data lives |
|---|---|---|
| Web explorer | Open a file without installing; inputs up to 20 MiB, subject to resource limits | Memory in the current tab; cleared on close, replacement, or reload |
| Terminal app | Work offline, explore larger files, or use shell workflows | Local SQLite cache by default; --no-cache uses temporary disk storage |
| CLI commands | Format, repair JSON, or validate without an interactive interface | Local processing; output goes to stdout or the file you choose |
The two interfaces share behavior, not sessions. Files, selected paths, and theme preferences do not sync between them. See the browser guide for a walkthrough, or the CLI reference for commands.
Open twig.wtf to select or drop JSON, YAML, or HAR files, paste data, or explore bundled examples. Files are processed in your browser and are not uploaded. Documents stay in the current tab's memory; closing, replacing, or reloading clears them. Only your Dark/Light theme preference is saved in browser local storage. No accounts, tracking, or document persistence.
The browser accepts inputs up to 20 MiB, with additional limits of 250,000 nodes and 128 MiB of estimated retained data. Actual memory use is higher and device-dependent. Dense or deeply nested files can hit these limits earlier. Use the installed TUI for larger files, offline use, and terminal workflows.
Click to inspect a row and click a selected container again to open it. Search
keys/values, jump to paths, and copy paths or complete selected values. Arrow
keys, j/k, h/l, Home/End, /, :, n/N, c, and y work while the
explorer has focus. Press t for Dark/Light, ? for help, and q to close
the document (the TUI quits). Enter after search or jump returns focus to
navigation; Esc cancels entry or returns to the parent. Browser shortcuts are
left intact. On narrow screens the current column is shown; breadcrumbs return to ancestors.
Previews are limited to four levels, 200 nodes, 30 children per container and 64K displayed characters. Copy value exports the complete selection, up to 10,000 nodes and 4 MiB. Clipboard access depends on browser permissions. Formatting and repair remain CLI features. The browser downloads application code from the site; install Twig when you need to work without loading a website.
Choose the instructions for the terminal you are using. Native Windows uses PowerShell; WSL uses the Linux instructions. No Rust or Python installation is needed for a prebuilt release.
Use Windows PowerShell 5.1 or PowerShell 7 on Windows x64. Open a regular
PowerShell tab in Windows Terminal; administrator access is not needed.
The installer needs tar.exe (included in Windows 10 1803+ and Windows 11).
Windows ARM64 and 32-bit binaries are not provided.
Download the installer, inspect it if desired, then run it:
Invoke-WebRequest -UseBasicParsing `
https://twig.wtf/install.ps1 `
-OutFile install.ps1
powershell -NoProfile `
-ExecutionPolicy Bypass `
-File .\install.ps1-ExecutionPolicy Bypass applies only to that installer process; it does not
change your saved execution policy. Organization policies can still block
scripts. If that happens, use the manual download instructions below or ask
your administrator; do not change an organization policy to install Twig.
The script downloads the latest release, verifies SHA-256 and the executable's
version, installs to %LOCALAPPDATA%\Programs\Twig\bin, and adds that folder to
your user PATH. It does not edit the system PATH. Close and reopen your
terminal, then check the installation:
twig --version
twig --help
twig 'C:\path\to\data.json'Choose a version or directory, or skip PATH changes:
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -Version v3.2.0 -InstallDir "$env:LOCALAPPDATA\Programs\Twig\bin"
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -NoPath
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -HelpClose any running Twig process before upgrading, then rerun the installer. Downloads and checksum verification happen before the installed executable is replaced. Failed downloads or mismatched versions leave the old executable intact. Temporary downloads are cleaned up on success and failure.
If scripts are restricted, download and verify the release in PowerShell:
$version = 'v3.2.0'
$asset = 'twig-x86_64-pc-windows-msvc.tar.gz'
$base = "https://github.com/workdone0/twig/releases/download/$version"
Invoke-WebRequest -UseBasicParsing "$base/$asset" -OutFile $asset
Invoke-WebRequest -UseBasicParsing "$base/$asset.sha256" -OutFile "$asset.sha256"
$expected = ((Get-Content "$asset.sha256" -Raw).Trim() -split '\s+')[0]
$actual = (Get-FileHash $asset -Algorithm SHA256).Hash
if ($expected -notmatch '^[a-fA-F0-9]{64}$' -or $actual -ine $expected) {
throw 'Checksum mismatch. Do not extract this archive.'
}
$dest = "$env:LOCALAPPDATA\Programs\Twig\bin"
New-Item -ItemType Directory -Force -Path $dest | Out-Null
tar -xzf $asset -C $dest twig.exe LICENSE
if ($LASTEXITCODE -ne 0) { throw 'Extraction failed.' }
& "$dest\twig.exe" --versionTo run twig by name, open Edit environment variables for your account from
the Start menu. Under User variables, select Path → Edit → New, add
%LOCALAPPDATA%\Programs\Twig\bin, and save. Keep the existing entries. Close
and reopen your terminal. The manual method overwrites the extracted files;
close Twig and verify the checksum before doing so.
- “twig is not recognized”: reopen Windows Terminal completely. Try
& "$env:LOCALAPPDATA\Programs\Twig\bin\twig.exe" --versionto check the installation independently of PATH. Use your chosen directory if customized. - An older version runs:
Get-Command twig -Alllists copies on PATH. Remove the obsolete executable or adjust your user PATH order, then open a new terminal. - Access denied while upgrading: close Twig in every terminal and retry. Choose a directory owned by your account; do not install into Program Files with the per-user installer.
- Missing
tar.exe: runGet-Command tar.exe. Use a Windows installation with the built-in tar tool available, or extract the verified archive with an archive utility and follow the manual PATH steps. - Using Git Bash or WSL: run the PowerShell installer for native Windows.
WSL is a separate Linux environment and uses
install.shinside WSL.
To uninstall, close Twig, delete its installation directory (the default
contains twig.exe and LICENSE), and remove that directory from your user PATH.
If you used a shared custom directory, remove only Twig's installed files.
twig --clear-cache removes cached data before uninstalling; config is separate.
curl -fsSL https://twig.wtf/install.sh | bashThe Bash installer downloads the latest release, verifies SHA-256 and the
executable's version, and installs to ~/.local/bin. It requires Bash, curl,
tar and its gzip support, install, and either sha256sum or macOS's shasum.
Linux uses GNU libc; Alpine/musl binaries are not provided. macOS builds target
11.0 or newer on Intel and Apple Silicon.
To inspect the script first or choose a version/directory:
curl -fsSL https://twig.wtf/install.sh -o install.sh
bash install.sh --help
bash install.sh --version v3.2.0 --to "$HOME/.local/bin" --yesIf twig is not found, add export PATH="$HOME/.local/bin:$PATH" to your shell
profile (~/.zshrc for zsh or ~/.bashrc for Bash), then open a new terminal.
Run twig --version and twig --help. For a custom directory, use that path.
command -v twig shows which executable your shell resolves.
Use --method build to compile the selected release with Cargo; it honors the
same destination. Interactive invocations ask before installing unless --yes
is supplied. Piped invocations run noninteractively. Rerun to upgrade through
an atomic executable replacement. To uninstall, remove the installed twig
file; configuration and caches are separate.
Download twig-<target>.tar.gz and its separate .tar.gz.sha256 file from
Releases.
| OS | Targets |
|---|---|
| Linux (GNU libc) | x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu |
| macOS | x86_64-apple-darwin, aarch64-apple-darwin |
| Windows x64 | x86_64-pc-windows-msvc |
Verify with sha256sum -c <checksum-file> on Linux or
shasum -a 256 -c <checksum-file> on macOS, then use tar -xzf <archive>.
Windows commands are shown above. Archives contain the executable and LICENSE.
These are native executables, not universal static binaries. Release .build.txt
assets record the commit, compiler, size, and available linkage diagnostics.
Clipboard support depends on the host desktop; SSH sessions may not provide it.
Binaries and the PowerShell script are not OS code-signed/notarized. Archives
have SHA-256 checksums and GitHub build provenance attestations.
Requires Rust 1.88+, Cargo, and a C compiler/linker for bundled SQLite. On Windows, use the MSVC Rust toolchain with Visual Studio Build Tools' C++ workload and Windows SDK; on macOS, install Xcode Command Line Tools; on Linux, use your distribution's C build toolchain.
cargo install --locked --git https://github.com/workdone0/twig --tag v3.2.0 twigCargo installs into its own bin directory, usually ~/.cargo/bin on Unix or
twig package on crates.io is unrelated.
Python is not needed to run the application.
twig samples/cloud_infrastructure.json
twig samples/k8s_manifest.yaml
twig samples/browser_navigation.har
# Format JSON to stdout or an output file
twig --print data.json --indent 4
twig --print data.json --indent 4 -o formatted.json
# Repair JSON, then format the repaired value
twig --fix --print broken.json -o repaired.json
# Validate/load without a terminal; force parsing for a cold benchmark
twig --check --rebuild-db data.json
# Keep no persistent cache
twig --no-cache secrets.json
# JSON stdin is available for non-interactive modes
cat response.json | twig --print -Output is plain JSON/YAML, suitable for piping. -o writes atomically after
successful parsing and can replace an existing file, including the input.
Prefer a separate output when reviewing repairs. Never redirect stdout to the
input path: the shell truncates that file before Twig reads it.
| Option | Behavior |
|---|---|
<FILE> |
Positional JSON, YAML, or HAR path; - means JSON stdin in CLI modes |
-p, --print |
Format JSON or a YAML document stream |
--fix |
Repair JSON and format it; may combine with --print |
-o, --output <PATH> |
Write formatted output atomically; requires print/fix |
-i, --indent <N> |
JSON indentation, 0–16 spaces, default 2; YAML uses its formatter |
--check |
Report validation/load time, size, nodes, throughput; conflicts with print/fix |
--rebuild-db |
Parse again even if a matching completed cache exists |
--no-cache |
Use a private temporary SQLite database |
--clear-cache |
Remove stored cache files and exit; takes no input file |
-h, --help |
Show help |
-V, -v, --version |
Show version; -v preserves the Python alias |
Format detection is case-insensitive: .yaml/.yml use YAML, other extensions
use JSON. HAR is ordinary JSON. There is no --file flag or live watch mode.
The TUI requires stdin and stdout attached to a terminal.
These navigation keys work in both explorers when focus is outside a text field. Search and path entry accept text until you press Enter or Esc.
| Action | Controls |
|---|---|
| Move up / down | ↑ / ↓, k / j |
| Open selected container | →, l, Enter |
| Return to parent | ←, h, Esc |
| First / last sibling | g / G, Home / End |
| Search keys and values | /, query, Enter |
| Next / previous match | n / N |
| Jump to a path | :, path, Enter |
| Copy path / entire selected value | c / y |
| Switch Dark / Light | t |
| Open help | ? |
| Dismiss search/jump | Esc |
| Dismiss help | Esc, ?, h, or Enter |
| Close document / quit | q closes the web document or quits the TUI; Ctrl+C quits the TUI in any mode |
Click a row to select it; click the selected container again to open it. Right-click in the columns returns to the parent. The TUI mouse wheel moves selection; the browser wheel scrolls the pane. In the TUI, clipboard ownership is kept while Twig runs; persistence after exit depends on the desktop clipboard manager. Failures are shown in the status message.
Paths look like .users[0].name; root arrays use .[0]. Keys containing
punctuation, spaces, or empty strings use JSON-quoted brackets, such as
.regions["us-east-1"] or .["a.b"]. This is a path lookup syntax, not a full jq
or JSONPath query language. YAML documents are wrapped in an array:
.[0].kind addresses the first document, and .kind is a shorthand fallback.
Search is a literal substring match, with ASCII case-insensitivity; % and _
are ordinary characters. Matches cycle in source traversal order, including
numeric array order. Non-ASCII characters match exactly.
Both interfaces separate a short preview from a complete export. The browser also limits exported text to 4 MiB; see the browser guide.
The inspector shows a limited preview. Clipboard y exports the complete
selected value, preserving scalar types and order, up to 10,000 nodes; larger
selections give an explicit error directing you to --print. Serialization does
not preserve original whitespace, comments, anchors, or quoting.
Themes: dark (default) and light, with the same colors in the TUI and web
explorer. Press t to toggle and save your preference. Legacy
catppuccin-mocha and solarized-dark settings both resolve to dark.
Unknown config keys are preserved. Unknown theme names fall back to the default;
custom theme definitions are not supported.
{"theme": "dark"}| Platform | Config directory (config.json) |
Cache directory |
|---|---|---|
| Linux | $XDG_CONFIG_HOME/twig or ~/.config/twig |
$XDG_CACHE_HOME/twig or ~/.cache/twig |
| macOS | ~/Library/Application Support/twig |
~/Library/Caches/twig |
| Windows | %APPDATA%\twig |
%LOCALAPPDATA%\twig |
On macOS, when the new config is missing, Twig imports the legacy Python config
from $XDG_CONFIG_HOME/twig/config.json or ~/.config/twig/config.json. An
existing new config is never overwritten by migration.
The installed terminal app makes no network requests or telemetry calls. Parsed values are stored unencrypted in private SQLite cache files. Unix cache directories are restricted to mode 0700 and published files to 0600; Windows uses profile ACLs.
Every load snapshots and hashes the input. Only completed caches matching the source contents and schema version can be reused. Failed/cancelled builds are never published. Concurrent loads use independent staging databases and publish immutable generations. A source change automatically selects a new generation.
New-format caches are pruned on load after seven days, or oldest-first when the
existing cache exceeds 512 MiB. A newly built cache may exceed that budget until
a subsequent load. Close other Twig processes and run twig --clear-cache to
remove caches, including older versions. Configuration is preserved.
--no-cache uses temporary disk storage, not an in-memory database. Normal exit
cleans up temporary data; abrupt OS/process termination may leave temporary
files. Sensitive data is not encrypted in either mode.
JSON is parsed into node events and inserted in batches of 1,024. It does not materialize the whole document tree. Memory still depends on the largest scalar, nesting/path lengths, SQLite working space, and requested exports. YAML parsing can buffer document state; bounded parser memory is not guaranteed.
Navigation fetches pages of at most 256 siblings, with a horizontal viewport for deep trees. Inspector previews have depth/node limits. Native search is a SQLite substring scan; broad searches on very large files can take time.
JSON input must contain a single document. Duplicate object keys and ambiguous
stored paths are rejected. Maximum supported nesting is 128 levels (the JSON
parser may reject at its own recursion boundary). The shared explorer model
supports YAML with JSON-compatible scalar types, sequences, and string-keyed mappings; non-finite
numbers, tagged values, and complex mapping keys are not supported. --print
uses the YAML value serializer and supports a wider YAML value model.
Measure cold ingestion explicitly:
cargo build --release --locked
python3 scripts/benchmark.py --binary target/release/twigThe benchmark generates a deterministic file and reports wall time and peak RSS.
--check uses MiB units. Cached loads still read/hash the source to verify it;
they are not evidence of parsing throughput. Performance depends on the file,
operation, and machine.
- Contributing: setup, tests, review, release workflow.
- Architecture: data flow and implementation boundaries.
- Migration: upgrading from Python 2.x, Rust 3.0, or 3.1.
- Privacy and security: browser memory, native caches, and reporting issues.
- 3.1 audit archive: historical findings and their resolution.
- Changelog and release notes.
Browser UI source lives in web/; the shared engine is in crates/twig-core.
Installation templates and guide styling live in website/. The site generates
its guides from these Markdown files and copies both installers from the
repository. The Python source remains on
legacy-python.
MIT — see LICENSE.