fx — JSON 的交互式查看器(jq 的 TUI 表亲)
是什么
fx 是 Anton Medvedev 在 2018 年发布、2022 年用 Go 重写的终端交互式 JSON 查看器。日常类比:
- jq:JSON 的 sed/awk —— 一条命令吐出过滤后的结果,不交互
- fx:JSON 的 less + 文件树 —— 在终端里打开一个大 JSON,方向键展开/折叠,斜杠搜索,回车跳转
- btop : top/htop = fx : jq —— 都是给原本一次性输出的命令行工具加一层”可以点、可以滚、可以折”的 TUI 皮
最小例子:
curl -s https://api.github.com/repos/antonmedv/fx | fxfx 立刻打开一个全屏 TUI:左边是可折叠的 JSON 树,方向键导航,e 展开全部,/ 搜索,q 退出。无参数时它就是 JSON 版的 less。
为什么重要
fx 在 19k+ stars 的位置不是偶然,原因有几层:
- 大 JSON 时代缺个交互入口:API 响应、kubectl、AWS CLI 输出动辄 100KB ~ 几 MB,jq 一行命令打出来全是滚动屏幕的瀑布;fx 让你先折叠看结构、再展开看细节,认知负担直接降一档
- 和 jq / yq 是搭档不是替代:jq/yq 是管道里的 filter,fx 是终点的 viewer —— 三者关系类似 grep + less 的关系,没有 fx 时人们用
jq . | less,但 less 不懂 JSON 结构 - 零配置上手:
brew install fx→cat x.json | fx,5 秒学会,比学 jq 的 DSL 门槛低 10 倍 —— 是 jq 的”前置入口工具” - 单 Go 二进制 + 跨平台 —— 老版 Node.js 的发行包袱在 2022 重写后甩掉
如果说 jq 是从无到有造了”shell 里处理 JSON”这个场景,fx 是把这个场景人性化 —— 让不会 jq 的人也能先看清 JSON 长什么样。
核心要点
fx 的心智模型可以拆成 三层:
-
TUI viewer(默认模式):把 JSON 当文件树渲染。空格折叠/展开节点,
e展开所有,E全部折叠,/搜索,g/G跳到首尾 —— 键位刻意抄 vim/less,老用户零迁移成本。 -
filter 模式(按
.进入):在底部输入栏写 jq 风格的过滤表达式,输入一个字符就实时刷新上方视图。这是它最杀手的功能 —— 写 jq 你得”猜对一次跑一次”,写 fx 你”边写边看”。 -
管道模式(无 TTY 时):检测到输出被重定向(
fx ... > out.json)时自动切非交互,行为退化成jq .。这让 fx 在脚本里也能当 JSON pretty-printer 用,不会破坏 pipeline。
三层叠加,让 fx 既能在调试场景做”打开看看”的 viewer,又能在 jq 表达式开发阶段做”实时 REPL”,还能在 CI 脚本里当透明的 pretty-printer。
实践案例
案例 1:打开一个大 API 响应
gh api repos/antonmedv/fx | fx打开后是可折叠的 JSON 树。方向键浏览,看到 owner 是个对象,按空格展开,再看到 permissions,再展开 —— 全程不需要写任何 jq 表达式。这是 fx 替代 jq . | less 的标准用法。
案例 2:和 jq 互补 —— fx 当前置探索器
实际工作流是这样:
# 第一步:先用 fx 探索结构kubectl get pods -o json | fx
# 第二步:心里有数后,写 jq 一行抓字段kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'fx 解决”我不知道这个 JSON 长什么样”的问题,jq 解决”我已经知道结构、要批量提字段”的问题。先 fx 后 jq 是最高效的组合。
案例 3:和 yq 联动看 K8s YAML
yq 把 YAML 转 JSON 后灌给 fx 交互浏览:
yq -o=json deployment.yaml | fxK8s 的 manifest 嵌套深,YAML 直接读眼花,转成 JSON 用 fx 的折叠树看更清楚。这是 yq 文档里推荐的 debugging 模式之一。
案例 4:在 fx 内写 jq 过滤器(实时 REPL)
cat huge-config.json | fx按 . 进入 filter 模式,输入 .users | map(.email) —— 每按一个字符上方视图都重渲染。写错语法立刻看到错误,写对就看到结果。开发完再 Ctrl+S 保存表达式,或退出后把表达式贴给 jq 跑批。
案例 5:和 fzf / ripgrep 搭管道
ripgrep 找出含敏感字段的 ndjson 行,fx 逐条展开看细节:
rg --json "password" logs/ | fxndjson 的多文档场景 fx 也支持 —— 它把每行当独立 JSON 加载,方向键在多文档之间切换。这是审查日志/审计的常见模式。
踩过的坑
-
同名工具混淆:GitHub 上至少有 3 个叫
fx的工具 —— Anton Medvedev 的这个 JSON viewer、一个前端 effects 库、一个 functional extensions 库。认准antonmedv/fx—— Homebrewbrew install fx默认就是它,但 npm 上其他同名包多到要小心。 -
Node 版和 Go 版并存:2018-2022 是 Node.js 写的(npm 安装),2022 后官方主推 Go 版(brew/binary)。两版功能基本一致但启动速度差 10 倍(Go 二进制冷启 30ms,Node 版要起 V8 引擎要 200ms+)。建议直接装 Go 版。
-
没 TTY 自动退化:在 CI 或者输出被重定向时,fx 检测到没 TTY 就不进 TUI,行为变成
jq .—— 这点设计合理但会让”为什么我看不到 UI”的初学者困惑半天。检查tty -s状态。 -
JS 表达式模式有安全风险:fx 支持用 JS 函数当 filter(
fx 'x => x.users.length')。这意味着 JSON 文件里的内容如果跟你的 filter 拼起来形成 JS 注入面,理论上能跑任意代码。处理不可信 JSON 时尽量用 jq 模式或只读 viewer。 -
大文件仍然一次性加载:默认把整个 JSON 读进内存才开始渲染。打开 5GB JSON 会卡几秒甚至 OOM —— 流式打开要看 ndjson 模式或外部预处理(jq
--stream切片后再 fx)。
适用 vs 不适用场景
适用:
- 探索陌生 JSON 结构(API 响应、kubectl 输出、配置文件)
- jq 表达式开发期的实时 REPL(边写边看)
- ndjson 日志逐条交互查看
- 临时 pretty-print(管道末端
... | fx在脚本里也能用) - 教学场景 —— 比 jq 友好太多,新人 5 分钟会用
不适用:
- CI/CD 自动化里抽字段 → 用 jq,无 TUI 开销
- YAML 直接处理 → 用 yq(先 yq 转 JSON 再 fx 也行,但多一步)
- 多 GB 流式处理 → fx 不擅长,用 jq
--stream - 需要 schema 校验 → 用 jsonschema / ajv
- 远程服务器无 TTY → 用
jq . | less替代
历史小故事(可跳过)
- 2018:Anton Medvedev 在 GitHub 发布 fx 1.0,Node.js 写的,配一个 30 秒的 GIF 演示
cat data.json | fx。HN 首页爆,第一周就 5k stars。 - 2019-2021:稳定迭代,加 themes、搜索、JS 表达式 filter,10k+ stars。
- 2022:官方宣布完全用 Go 重写,理由是单二进制、启动快、不依赖 Node runtime。Node 版仍可用但进入维护模式。
- 2023:进入 Homebrew、apt、scoop、nix 默认仓库,K8s 圈口口相传”调试 JSON 用 fx”。
- 2024-2026:19k+ stars,是 jq 之后最常被推荐的 JSON 工具;Anton 开始做 fx Pro(带 schema 推断的付费版)。
学到什么
-
给老 CLI 加 TUI 是一个反复出现的成功 pattern —— top → htop → btop,jq → fx,git → lazygit,docker → lazydocker。每个 CLI 工具都值得问一句”它的 TUI 在哪”。
-
filter 实时反馈 = 学习曲线砍半 —— jq 的 DSL 老有人学不会,是因为反馈周期长(写、跑、看错误、改);fx 让反馈降到键击级别,新人上手指数级变快。这是 REPL 思想在 CLI 工具里的胜利。
-
同生态做”探索版 + 批量版”组合 —— fx 不试图替代 jq,而是当它的前置入口。这种”互补不替代”的定位让两者都活得很好,比正面竞争健康。
-
Node → Go 的重写代价值不值 —— 2022 重写后用户从 npm 迁到 brew 经历了一次小阵痛,但启动速度从 200ms 降到 30ms,长期收益远大于一次性迁移成本。这是工具类项目”语言换跑道”的成功案例。
延伸阅读
- 官方站:fx.wtf(一页文档全在这,5 分钟看完)
- GitHub README:antonmedv/fx(GIF 演示直观)
- 作者博客:medv.io(Anton 写的 fx 设计反思和重写故事)
- 同类对比:jless(Rust 写的 fx 对手,键位更 vim)
关联
- jq —— 心智模型同源;fx 是 jq 的 TUI 前置入口,先 fx 探索再 jq 批量
- yq ——
yq -o=json | fx是看复杂 K8s manifest 的标准管道 - btop —— 同属”给老 CLI 加 TUI”的设计模式
- fzf —— ripgrep + jq + fzf + fx 是 DevOps 的 JSON 探索四件套
- ripgrep ——
rg --json | fx把搜索结果交互化 - claude-code —— Claude Code 在调试 API 响应时常推荐先 fx 探索再写 jq 表达式
反向链接
- btop —— btop — bashtop 三代 C++ 版,五面板一屏的彩色资源监控器
- claude-code —— Claude Code — Anthropic 终端编程助手
- curlie —— curlie — curl 的能力 + HTTPie 的语法
- dasel —— dasel — 一把刀同时切 JSON / YAML / TOML / XML / CSV
- fzf —— fzf — 命令行模糊查找
- gron —— gron — 把 JSON 拍平成 grep 能吃的赋值行
- httpie —— HTTPie — curl 的人话版本
- jc —— jc — 把 100+ Unix 命令的输出一键 JSON 化
- jq —— jq — JSON 的 sed/awk
- ripgrep —— ripgrep — Rust 写的现代 grep