Modern tooling often assumes a perfect world:
latest Linux, internet access, package managers, and rebuildable binaries.
Reality is different.
In many production environments — especially enterprise, legacy, or air-gapped systems —
those assumptions break down.
That gap is why I built jq-lite.
The Problem: jq Is Great — Until You Can’t Use It
jq is an excellent JSON processor.
But in real operations, I kept hitting walls:
Legacy UNIX systems with outdated glibc
Air-gapped environments with no package repositories
Minimal containers without build tools
Environments where “just install jq” was not an option
In those cases, JSON processing didn’t disappear —
the need became more critical.
Shell scripts still had to be reliable.
Automation still had to work.
The Idea: A jq-Compatible Tool That Never Breaks Scripts
I didn’t want another JSON tool.
I wanted a tool that could be:
Dropped into restricted systems
Trusted in shell scripts
Stable across years, not releases
So I built jq-lite with three strict rules:
Design Rule #1: Pure Perl, No Dependencies
jq-lite is written in pure Perl.
No native extensions
No external libraries
No compilation step
If Perl exists, jq-lite runs.
That means it works on:
legacy Linux / UNIX
minimal containers
offline environments
systems where only base OS tools are allowed
Perl is still one of the most widely deployed runtimes in the world —
especially in places modern tooling forgot.
Design Rule #2: jq Compatibility Where It Matters
jq-lite aims to be jq-compatible in daily CLI usage:
echo '{}' | jq-lite --arg greeting hello '.hello = $greeting'
Output:
{
"hello": "hello"
}
The goal isn’t to clone every feature,
but to support the jq patterns people actually use in automation.
Design Rule #3: A Stable CLI Contract (This Is the Important Part)
Here’s the part that made jq-lite different.
jq-lite defines a documented CLI contract:
exit codes
error categories
stderr prefixes
stdout behavior on failure
And that contract is tested.
Exit Code Meaning
0 Success
1 -e used and result was false / null / empty
2 Compile error
3 Runtime error
4 Input error
5 Usage error
This means shell scripts can safely rely on jq-lite:
if jq-lite -e '.enabled' config.json; then
deploy
fi
No surprises.
No silent behavior changes.
In operations, this matters more than features.
Why Not Rewrite It in Rust or Go?
I get this question a lot.
Because the problem wasn’t performance or language fashion.
The problem was deployability and longevity.
Perl already exists on:
old servers
enterprise systems
restricted environments
Adding jq-lite doesn’t require changing the environment —
just using what’s already there.
Who Is jq-lite For?
jq-lite is not for everyone.
It is for people who:
maintain legacy systems
write shell scripts that must survive years
operate in restricted or offline environments
care about CLI behavior as a contract, not a suggestion
If you’ve ever thought
“this script must not break in five years”
— jq-lite is for you.
Where to Find It
GitHub: https://github.com/kawamurashingo/JQ-Lite
CLI Contract: https://github.com/kawamurashingo/JQ-Lite/blob/main/docs/cli-contract.md
CPAN: https://metacpan.org/release/JQ-Lite
Alpine Linux package available
Final Thought
Modern tools optimize for speed of change.
jq-lite optimizes for stability over time.
Sometimes, that’s the more important optimization.
Author
川村慎吾(Shingo Kawamura)
SRE / Infrastructure Engineer
CPAN author of jq-lite
Top comments (1)
Thanks for reading!
jq-lite focuses on long-term CLI stability in legacy and constrained environments.
Feedback and real-world use cases are very welcome.