Opening a large source file in full makes it hard to choose what to read. Put the zat CLI in front of that step: it prints exported symbols and line ranges first, then you Read only the spans that look useful.

📑Table of Contents
  1. What zat lists, and what it leaves out
  2. Pick an install path (Homebrew / Nix / mise / cargo)
  3. Supported languages, and when not to call zat
  4. A checklist before you hand the file to an agent
  5. Install-path comparison
  6. FAQ
  7. Summary and next step

Official README rule

The official README targets LLM coding agents and says to prefer zat over cat or Read when you need signatures. Unsupported files exit 1, so an unknown extension is not treated as success.

This guide covers:

  • what zat shows and hides
  • the Homebrew / Nix / mise / cargo install split
  • language limits
  • a pre-agent checklist

Token savings are the main intended benefit, although there is no official benchmark. Any reduction depends on repository size and how you invoke the tool.


Checks this article answers


What zat lists, and what it leaves out

Zat produces a map of a file’s public surface. It is not a full-file reader.

Official definition

The official README describes it as a code outline viewer that displays exported symbols and their line numbers at a glance.

Its output consists of the signatures of public or exported symbols together with their start–end line ranges.

  • Shown: public or exported symbol signatures, plus a start–end line range
  • Shown inside types: struct fields, enum variants, and interface members
  • Stripped: pub and export modifiers
  • Out of scope: private symbols
  • Added from v0.5.0: import and include lines for JavaScript / TypeScript / Python / Java / C / C++ / C# / Ruby / Rust / Go

Output example

A typical call is zat src/lib.rs. The README example looks like struct OutlineEntry { // L8-L12. From v0.5.2, multi-line nodes print ranges such as L26-L42. You do not have to guess the end line from a single start number.


What stays hidden

Do not ask zat to reconstruct what it deliberately hides. Private function bodies, test-only helpers, and the intent behind comments remain invisible. The intended workflow is to sketch the public API first and then open only the specific ranges you need. This approach does not replace full-text search or an implementation review.


Pick an install path (Homebrew / Nix / mise / cargo)

The shortest path depends on your environment.

  • On macOS, the official tap is the fast route
  • On Nix, split nixpkgs from numtide by pin freshness
  • If you want to track source yourself, use mise or cargo

Versions on the research date

As of 2026-08-18 the official latest tag is v0.5.4 (2026-05-06).

If you need 0.5.4 behavior or docs (including the mise path), do not freeze on the nixpkgs 0.5.3 pin.


Install commands

Install options:

  1. Homebrew: brew install bglgwyng/tap/zat
  2. nixpkgs: nix profile install nixpkgs#zat, or nix run nixpkgs#zat -- <FILE> / nix-shell -p zat
  3. numtide flake: nix run github:numtide/llm-agents.nix#zat -- src/main.rs
  4. mise: mise use -g github:bglgwyng/zat
  5. cargo: cargo install --git https://github.com/bglgwyng/zat
  6. Binaries: GitHub Releases for macOS aarch64 / x86_64 and Linux x86_64
# Official file outline
zat src/lib.rs

# One-shot Nix run
nix run github:numtide/llm-agents.nix#zat -- src/main.rs

Install limits

Limits first:

  • zat has no --version flag
  • that is why numtide’s installCheck runs zat src/main.rs
  • Home Manager can set programs.zat.enable and optionally register a Claude Code rule
  • the CLI itself is GPL-3.0-only; Nix packaging code in numtide / Qumulo is MIT
  • it is not the zathura PDF viewer

If the goal is a faster terminal search loop, that is a different AI/IT job than zat. A fzf, ripgrep, and gh toolkit finds text and history. zat only maps public symbols. Keep those roles separate.


Supported languages, and when not to call zat

An extension that is not in the README table exits 1. Do not pass a directory.

Official language table

The official table covers:

  • JavaScript / JSX / CJS / MJS
  • TypeScript / TSX / MTS / CTS
  • Rust, Python, Go, Java
  • C / C++, C#, Swift, Kotlin, Haskell, and Ruby

The agent note also lists Markdown headings.


Parser behavior on failure

Every parser is tree-sitter. Upstream tree-sitter can still return a tree on syntax errors, but zat does not treat unsupported languages as success.

  • v0.5.3 restated that unknown types exit 1
  • the cat -n fallback was removed in v0.5.0

File-only limit

From v0.5.0 the CLI is file-only. Directory mode is gone.

The nixpkgs blurb still says “files and directories”; treat that as packaging copy, not current CLI behavior. Because only public symbols appear, zat is a poor fit for private-implementation review, generated-code diffs, or config-file dumps.


When the task is a page, not an outline

If the task is a page, not a source outline, pick another CLI.

Zat is only a public-symbol map for source files.


When to skip zat

Skip zat when any of these is true:

  • the extension is not in the table
  • you need a private implementation, not a public surface
  • you want a directory listing (current CLI cannot do that)

Then go to Read or search instead.


A checklist before you hand the file to an agent

Split zat and Read by whether you need signatures or implementations. Do not send the whole file first.

Official agent rule

The official suggestion is to put this in CLAUDE.md / AGENTS.md:

  • prefer zat over cat or Read when you need signatures
  • once line numbers exist, open that span with Read(offset, limit)

That order is the reproducible way to pursue token savings. There is still no official savings benchmark, so do not promise a specific number.


Four questions on the spot

Four questions on the spot:

  1. Is the extension in the table? If not, do not call zat.
  2. Do you need a public map or a private implementation? The latter needs more than zat.
  3. If a range prints, Read only that range. If nothing matches, do not read.
  4. Is the pin new enough? Do not freeze nixpkgs 0.5.3 if you need 0.5.4 behavior.
  • Extension is in the README table
  • You want public symbols, not a private body
  • You pass one file, not a directory
  • AGENTS.md has one paragraph: outline first, then ranged Read
  • You recorded whether the pin is 0.5.3 or 0.5.4

Forks and catalogs

The Qumulo/llm-agents fork also lists zat under Memory & Code Intelligence. On 2026-08-18 it was 36 commits behind upstream. Unless you already live on that fork, track versions via numtide or the official tap / cargo path.

The third-party Hermes Atlas catalog independently lists zat as a GPL-3.0-only source build. Use the catalog to confirm the package exists; use the README for the language table.


Install-path comparison

Choose the path by the pin you get and by whether the docs still mention directories.

Comparison table

Path Version on research date Best fit Watch-out
GitHub README / Releases v0.5.4 Follow upstream exactly No --version
Homebrew tap As documented in README Fastest on macOS Tap name is bglgwyng/tap/zat
nixpkgs unstable 0.5.3 Existing Nix env Blurb still says directory; CLI is file-only since v0.5.0
numtide/llm-agents.nix 0.5.4 Already on the agent flake nix run ...#zat -- <FILE>; has installCheck
Qumulo/llm-agents Upstream fork Existing fork users 36 commits behind on 2026-08-18
mise / cargo –git Latest source You track tags yourself Build time

Table sources

Sources: bglgwyng/zat, nixpkgs unstable zat, numtide/llm-agents.nix, Qumulo/llm-agents (as of August 2026).


Pin difference

“It installs with Nix” is not one choice. 0.5.3 and 0.5.4 are different pins. Trusting the leftover directory wording and passing a folder will fail on the current CLI.


FAQ

zat versus cat or Read

Q. How is zat different from cat or Read?

  • It prints public symbols and line ranges only
  • It does not print implementation bodies
  • The official docs say to run zat first when you need signatures
  • Then Read just those ranges

Supported languages

Q. Which languages work?

  • README table: JavaScript / TypeScript, Rust, Python, Go, Java, C / C++, C#, Swift, Kotlin, Haskell, and Ruby
  • Markdown is mentioned in the agent note
  • Anything else exits 1
  • Current builds do not fall back to cat -n

nixpkgs or numtide

Q. On Nix, should I use nixpkgs or numtide?

  • On the research date, numtide is 0.5.4 and nixpkgs is 0.5.3
  • Prefer numtide, or the official tap / cargo, if you want the newer tag
  • Keep 0.5.3 only if you must leave an existing nixpkgs pin alone

Directory input

Q. Can I pass a directory?

  • No. Directory mode was removed in v0.5.0
  • Call one file at a time
  • A leftover “directory” phrase in nixpkgs copy is not current CLI behavior

License

Q. What is the license?

  • The tool is GPL-3.0-only
  • Nix packaging code in numtide / Qumulo is MIT
  • Check the binary and the packaging separately before you vendor either

Summary and next step

zat is a public-surface map, not a full-file reader. For an AI or IT workflow, four checks are enough: public surface vs implementation, language support, and whether the pin is 0.5.3 or 0.5.4.

A short next action:

  1. Confirm your usual language is in the README table.
  2. Pick one install path and run zat <FILE> on a single file.
  3. Add one AGENTS.md paragraph: outline first, then ranged Read.
  4. If you use Nix, write down the 0.5.3 / 0.5.4 pin.

The canonical docs stay on the bglgwyng/zat README. If you later want another language, wait for the table to grow, or keep unsupported files out of zat.

Related articles:

krona23

Author

krona23

Over 20 years in the IT industry, serving as Division Head and CTO at multiple companies running large-scale web services in Japan. Experienced across Windows, iOS, Android, and web development. Currently focused on AI-native transformation. At DevGENT, sharing practical guides on AI code editors, automation tools, and LLMs in three languages.

DevGENT about →

Leave a Reply

Trending

Discover more from DevGENT

Subscribe now to keep reading and get access to the full archive.

Continue reading