gnarl
Find the gnarled code in your Zig. See exactly why it is gnarled. Cut it with a plan, and keep it cut.
gnarl measures every function in a Zig codebase (cyclomatic and cognitive complexity, logical lines, nesting depth, parameters) and then does the part other metrics tools leave to you: it explains each number construct by construct, points at the lines worth lifting out, predicts what the refactor will leave before you make it, and holds the line in CI so the debt you have cannot grow.
Get started See it work GitHub
- Zig’s rules, not C’s. A
tryis not a branch,catch unreachablehas no other path, and a flatswitchof forty prongs is one decision to a reader. - Every number explained. Each construct counted, where it is, what it costs, and how much of that is depth.
- Where to cut, and what the cut leaves. The statements that carry the cost, the ranges worth lifting out, and for any range: the new function’s numbers, its parameters, what it gives back, and the jumps that would need reworking.
- A ratchet for CI. Freeze the debt you have; fail only what is new or worse.
- Syntax only, and fast. The compiler’s own parser,
std.zig.Ast: no build, no configuration, all of Zig’s standard library in a fifth of a second.
A quick look
$ gnarl .
cyclomatic cognitive lines nesting params weighted location function
11! 33!! 23 5! 4 4 tally.zig:7 tally
1 function in 1 file: 1 over a critical threshold (!!), 0 more over a warning one (!).
$ gnarl --explain tally .
...
worth lifting out, best first; --explain path:A-B says more of each:
24-34 a function of cyclomatic 5, cognitive 8, params 4; tally keeps cyclomatic 7, cognitive 19; gives back total
15-19 a function of cyclomatic 2, cognitive 2, params 2; tally keeps cyclomatic 10, cognitive 27
! is over a warning limit, !! over a critical one. The walkthrough takes this function from report to refactor.
Get started
brew install kmoneil/tap/gnarl # macOS, Linux
Or take a binary for Linux, macOS or Windows from the latest release, each with its SHA256SUMS line and a build-provenance attestation, or build it from source with Zig 0.17:
git clone https://github.com/kmoneil/gnarl
cd gnarl
zig build -Doptimize=ReleaseFast
cp zig-out/bin/gnarl ~/.local/bin/ # or anywhere on your PATH
Then, in any Zig project:
gnarl . # what is over a limit, worst first
gnarl --explain <function> . # why, construct by construct, and where to cut
gnarl --diff HEAD # after a change: what it did, function by function
gnarl --check . # in CI: exit 1 on what is new or worse
Run gnarl skill to print the guide an AI agent needs to work with gnarl; gnarl skill --install <dir> writes a skill where your agent reads them, which has it run gnarl skill, so it is never out of date.