Comparison
jc-rs, jc, and jq
jc is the original tool that decided this category: a Python program that turns command output into JSON. jc-rs implements those schemas in a compiled binary and measures its output against the shared fixture corpus. jq starts after that conversion: it reads JSON and selects, reshapes, or aggregates it.
jc-rs
Rust. One static binary, nothing to install alongside it. Runs where a language runtime cannot go: scratch containers, embedded images, a browser tab.
jc
Python, by Kelly Brazil. The original, and the tool whose JSON schemas both implementations produce. github.com/kellyjonbrazil/jc
Where jq fits
jq does not know where the columns in ss output end, and jc-rs does not provide jq's query language. Put them next to each other: the parser establishes the records, then jq asks a question of those records.
raw output
ss -tlnpparse
jc-rs --ssquery JSON
jq '[.[].local_port] | unique'For quoting, exit handling, and complete Bash examples, read Bash, jc-rs, and jq.
Side by side
This is what decides whether it can go in a scratch container or on an appliance.
Whole-process wall time per invocation. Repeated 200 times, that is 0.8 s versus 21.8 s in this benchmark.
934/934 oracle-valid fixture pairs have no structural or value differences under the published JSON comparison. Test the inputs your pipeline depends on.
The converter on the front page of this site is the parser set itself, running locally.
Measured process time
The harness measures complete process wall time, once per invocation. Repeating the cold start row 200 times totals 21.8 seconds for jc and 0.8 seconds for jc-rs on the measured host. The larger fixture rows below measure parsing and process overhead together; the benchmark does not assign those milliseconds to individual runtime components.
make bench-vs-jc.Switching
For a parser and input that match the compatibility contract, the command name can be the only change. Compare representative output before moving a production pipeline.
- ps aux | jc --ps | jq '.[0]' + ps aux | jc-rs --ps | jq '.[0]'
The binary is called jc-rs precisely so both can sit in PATH at once. Release archives carry a jc alias for anyone who wants the shorter name, and nothing installs it by default.
When jc is the better pick
- You are writing Python and want the parsers as a module in the same process. jc-rs gives you a Rust crate and a WebAssembly package, not a Python one.
- You need a parser jc-rs has not implemented. The set is close but not identical, and the index lists exactly what ships.
- Startup time is irrelevant to you and a runtime is already installed. One invocation at a prompt does not care about 110 ms.
The compatibility claim, and how to check it
“Same JSON” is easy to say, so jc-rs measures it: 934 of 934 oracle-valid pairs drawn from the full corpus have no structural or value differences under the published comparison, and the run fails CI below 100%. What the number excludes is published next to it.
How the number is producedCold start figure above: 109 ms against 4 ms, the widest gap in the measured set. Method: one fresh process per run, fastest result retained from repeated runs.